246 * #include <deal.II/base/quadrature_lib.h>
247 * #include <deal.II/base/function.h>
248 * #include <deal.II/lac/affine_constraints.h>
249 * #include <deal.II/lac/vector.h>
250 * #include <deal.II/lac/full_matrix.h>
251 * #include <deal.II/lac/solver_cg.h>
252 * #include <deal.II/lac/petsc_sparse_matrix.h>
253 * #include <deal.II/lac/petsc_sparse_matrix.h>
254 * #include <deal.II/lac/petsc_vector.h>
255 * #include <deal.II/lac/petsc_solver.h>
256 * #include <deal.II/lac/petsc_precondition.h>
257 * #include <deal.II/grid/grid_generator.h>
258 * #include <deal.II/grid/tria_accessor.h>
259 * #include <deal.II/grid/tria_iterator.h>
260 * #include <deal.II/dofs/dof_handler.h>
261 * #include <deal.II/dofs/dof_accessor.h>
262 * #include <deal.II/dofs/dof_tools.h>
263 * #include <deal.II/fe/fe_values.h>
264 * #include <deal.II/fe/fe_q.h>
265 * #include <deal.II/numerics/vector_tools.h>
266 * #include <deal.II/numerics/data_out.h>
267 * #include <deal.II/numerics/error_estimator.h>
268 * #include <deal.II/base/utilities.h>
269 * #include <deal.II/base/conditional_ostream.h>
270 * #include <deal.II/base/index_set.h>
271 * #include <deal.II/lac/sparsity_tools.h>
272 * #include <deal.II/distributed/tria.h>
273 * #include <deal.II/distributed/grid_refinement.h>
274 * #include <deal.II/lac/vector.h>
275 * #include <deal.II/base/convergence_table.h>
276 * #include <deal.II/base/timer.h>
277 * #include <deal.II/base/parameter_handler.h>
278 * #include <deal.II/grid/grid_tools.h>
279 * #include <deal.II/fe/mapping_q.h>
284 * #include <iostream>
295 * #define CHECK_MAX_PRINCIPLE 0
299 * LOG FOR LEVEL SET FROM -1 to 1
303 * #define ENTROPY_GRAD(phi,phix) 2*phi*phix*((1-phi*phi>=0) ? -1 : 1)/(
std::abs(1-phi*phi)+1E-14)
310 * This is a solver
for the transpor solver.
311 * We assume the velocity is divergence free
312 * and solve the equation in conservation form.
314 * ---------- NOTATION ----------
316 * We use notation popular in the literature of conservation laws.
317 * For
this reason the solution is denoted as u, unm1, unp1, etc.
318 * and the velocity is treated as vx, vy and vz.
322 *
class LevelSetSolver
342 * BOUNDARY CONDITIONS
346 *
void set_boundary_conditions(std::vector<types::global_dof_index> &boundary_values_id_u,
347 * std::vector<double> boundary_values_u);
375 *
void nth_time_step();
385 * LevelSetSolver (
const unsigned int degree_LS,
386 *
const unsigned int degree_U,
387 *
const double time_step,
390 *
const bool verbose,
391 * std::string ALGORITHM,
392 *
const unsigned int TIME_INTEGRATION,
401 * ASSEMBLE MASS (and other) MATRICES
405 *
void assemble_ML();
407 *
void assemble_MC();
411 * LOW ORDER METHOD (DiJ Viscosity)
415 *
void assemble_C_Matrix();
425 *
void assemble_EntRes_Matrix();
429 * FOR MAXIMUM PRINCIPLE
455 * std::string algorithm);
458 * std::string algorithm);
466 *
void get_sparsity_pattern();
467 *
void get_map_from_Q1_to_Q2();
470 * std::shared_ptr<PETScWrappers::PreconditionBoomerAMG> preconditioner,
473 *
void save_old_solution();
474 *
void save_old_vel_solution();
483 *
const std::vector<types::global_dof_index> &indices,
484 * std::vector<PetscScalar> &values);
486 *
const std::vector<types::global_dof_index> &indices,
487 * std::map<types::global_dof_index, types::global_dof_index> &map_from_Q1_to_Q2,
488 * std::vector<PetscScalar> &values);
494 * FINITE ELEMENT SPACE
502 *
IndexSet locally_relevant_dofs_LS;
512 * OPERATORS times SOLUTION VECTOR
525 * std::shared_ptr<PETScWrappers::PreconditionBoomerAMG> MC_preconditioner;
532 * std::vector<types::global_dof_index> boundary_values_id_u;
533 * std::vector<double> boundary_values_u;
540 * FOR FIRST ORDER VISCOSITY
547 * FOR ENTROPY VISCOSITY
553 * FOR FCT (flux and limited flux)
582 * NON-GHOSTED VECTORS
620 *
double solver_tolerance;
621 *
double entropy_normalization_factor;
629 * std::string ALGORITHM;
630 *
unsigned int TIME_INTEGRATION;
634 * std::map<types::global_dof_index, types::global_dof_index> map_from_Q1_to_Q2;
635 * std::map<types::global_dof_index, std::vector<types::global_dof_index> > sparsity_pattern;
639 * LevelSetSolver<dim>::LevelSetSolver (
const unsigned int degree_LS,
640 *
const unsigned int degree_U,
641 *
const double time_step,
644 *
const bool verbose,
645 * std::string ALGORITHM,
646 *
const unsigned int TIME_INTEGRATION,
650 * mpi_communicator (mpi_communicator),
651 * degree_LS(degree_LS),
652 * dof_handler_LS (triangulation),
654 * degree_U(degree_U),
655 * dof_handler_U (triangulation),
657 * time_step(time_step),
661 * ALGORITHM(ALGORITHM),
662 * TIME_INTEGRATION(TIME_INTEGRATION),
665 * pcout <<
"********** LEVEL SET SETUP **********" << std::endl;
670 * LevelSetSolver<dim>::~LevelSetSolver ()
672 * dof_handler_LS.clear ();
673 * dof_handler_U.clear ();
692 * this->locally_relevant_solution_vx = locally_relevant_solution_vx;
693 * this->locally_relevant_solution_vy = locally_relevant_solution_vy;
696 * initialize old vectors with current solution,
this just happens the first time
700 * locally_relevant_solution_vx_old = locally_relevant_solution_vx;
701 * locally_relevant_solution_vy_old = locally_relevant_solution_vy;
711 * this->locally_relevant_solution_vx = locally_relevant_solution_vx;
712 * this->locally_relevant_solution_vy = locally_relevant_solution_vy;
713 * this->locally_relevant_solution_vz = locally_relevant_solution_vz;
716 * initialize old vectors with current solution,
this just happens the first time
720 * locally_relevant_solution_vx_old = locally_relevant_solution_vx;
721 * locally_relevant_solution_vy_old = locally_relevant_solution_vy;
722 * locally_relevant_solution_vz_old = locally_relevant_solution_vz;
733 *
void LevelSetSolver<dim>::set_boundary_conditions(std::vector<types::global_dof_index> &boundary_values_id_u,
734 * std::vector<double> boundary_values_u)
736 * this->boundary_values_id_u = boundary_values_id_u;
737 * this->boundary_values_u = boundary_values_u;
756 * save_old_vel_solution();
762 * this->locally_relevant_solution_vx=locally_relevant_solution_vx;
763 * this->locally_relevant_solution_vy=locally_relevant_solution_vy;
776 * save_old_vel_solution();
782 * this->locally_relevant_solution_vx=locally_relevant_solution_vx;
783 * this->locally_relevant_solution_vy=locally_relevant_solution_vy;
784 * this->locally_relevant_solution_vz=locally_relevant_solution_vz;
799 * -------------------------------------------------------------------------------
800 * ------------------------------ COMPUTE SOLUTIONS ------------------------------
801 * -------------------------------------------------------------------------------
805 *
void LevelSetSolver<dim>::nth_time_step()
807 * assemble_EntRes_Matrix();
813 *
if (TIME_INTEGRATION==FORWARD_EULER)
814 * compute_solution(unp1,un,ALGORITHM);
816 * compute_solution_SSP33(unp1,un,ALGORITHM);
819 * BOUNDARY CONDITIONS
822 * unp1.set(boundary_values_id_u,boundary_values_u);
826 * CHECK MAXIMUM PRINCIPLE
829 *
if (CHECK_MAX_PRINCIPLE)
831 * compute_bounds(un);
832 * check_max_principle(unp1);
836 * pcout <<
"*********************************************************************... "
837 * << unp1.min() <<
", " << unp1.max() << std::endl;
840 * save_old_solution();
845 * --------------------------------------------------------------------
846 * ------------------------------ SETUP ------------------------------
847 * --------------------------------------------------------------------
851 *
void LevelSetSolver<dim>::setup()
853 * solver_tolerance=1
E-6;
854 * degree_MAX =
std::max(degree_LS,degree_U);
858 * SETUP FOR DOF HANDLERS
863 * dof_handler_LS.distribute_dofs (fe_LS);
864 * locally_owned_dofs_LS = dof_handler_LS.locally_owned_dofs ();
871 * dof_handler_U.distribute_dofs (fe_U);
872 * locally_owned_dofs_U = dof_handler_U.locally_owned_dofs ();
881 * constraints.clear ();
883 * constraints.reinit (locally_owned_dofs_LS, locally_relevant_dofs_LS);
885 * constraints.reinit (locally_relevant_dofs_LS);
888 * constraints.close ();
892 * NON-GHOSTED VECTORS
896 * MPP_uL_solution.reinit(locally_owned_dofs_LS,mpi_communicator);
897 * NMPP_uH_solution.reinit(locally_owned_dofs_LS,mpi_communicator);
898 * RHS.reinit(locally_owned_dofs_LS,mpi_communicator);
899 * uStage1_nonGhosted.reinit (locally_owned_dofs_LS,mpi_communicator);
900 * uStage2_nonGhosted.reinit (locally_owned_dofs_LS,mpi_communicator);
901 * unp1.reinit (locally_owned_dofs_LS,mpi_communicator);
902 * MPP_uH_solution.reinit (locally_owned_dofs_LS,mpi_communicator);
905 * vectors
for lumped mass
matrix
908 * ML_vector.reinit(locally_owned_dofs_LS,mpi_communicator);
909 * inverse_ML_vector.reinit(locally_owned_dofs_LS,mpi_communicator);
910 * ones_vector.reinit(locally_owned_dofs_LS,mpi_communicator);
914 * operators times solution
917 * K_times_solution.reinit(locally_owned_dofs_LS,mpi_communicator);
918 * DL_times_solution.reinit(locally_owned_dofs_LS,mpi_communicator);
919 * DH_times_solution.reinit(locally_owned_dofs_LS,mpi_communicator);
925 * R_pos_vector_nonGhosted.reinit (locally_owned_dofs_LS,mpi_communicator);
926 * R_neg_vector_nonGhosted.reinit (locally_owned_dofs_LS,mpi_communicator);
927 * umin_vector.reinit (locally_owned_dofs_LS,mpi_communicator);
928 * umax_vector.reinit (locally_owned_dofs_LS,mpi_communicator);
932 * GHOSTED VECTORS (used within some assemble process)
936 * uStage1.reinit (locally_owned_dofs_LS,locally_relevant_dofs_LS,mpi_communicator);
937 * uStage2.reinit (locally_owned_dofs_LS,locally_relevant_dofs_LS,mpi_communicator);
938 * unm1.reinit (locally_owned_dofs_LS,locally_relevant_dofs_LS,mpi_communicator);
939 * un.reinit (locally_owned_dofs_LS,locally_relevant_dofs_LS,mpi_communicator);
940 * MPP_uL_solution_ghosted.reinit (locally_owned_dofs_LS,locally_relevant_dofs_LS,mpi_communicator);
941 * MPP_uLkp1_solution_ghosted.reinit (locally_owned_dofs_LS,locally_relevant_dofs_LS,mpi_communicator);
942 * NMPP_uH_solution_ghosted.reinit (locally_owned_dofs_LS,locally_relevant_dofs_LS,mpi_communicator);
945 * init vectors
for vx
948 * locally_relevant_solution_vx.reinit (locally_owned_dofs_U,locally_relevant_dofs_U,mpi_communicator);
949 * locally_relevant_solution_vx_old.reinit (locally_owned_dofs_U,locally_relevant_dofs_U,mpi_communicator);
952 * init vectors
for vy
955 * locally_relevant_solution_vy.reinit (locally_owned_dofs_U,locally_relevant_dofs_U,mpi_communicator);
956 * locally_relevant_solution_vy_old.reinit (locally_owned_dofs_U,locally_relevant_dofs_U,mpi_communicator);
959 * init vectors
for vz
962 * locally_relevant_solution_vz.reinit (locally_owned_dofs_U,locally_relevant_dofs_U,mpi_communicator);
963 * locally_relevant_solution_vz_old.reinit (locally_owned_dofs_U,locally_relevant_dofs_U,mpi_communicator);
969 * R_pos_vector.reinit(locally_owned_dofs_LS,locally_relevant_dofs_LS,mpi_communicator);
970 * R_neg_vector.reinit(locally_owned_dofs_LS,locally_relevant_dofs_LS,mpi_communicator);
982 * dof_handler_LS.locally_owned_dofs(),
984 * locally_relevant_dofs_LS);
985 * MC_matrix.reinit (dof_handler_LS.locally_owned_dofs(),
986 * dof_handler_LS.locally_owned_dofs(),
987 * dsp, mpi_communicator);
988 * Cx_matrix.reinit (dof_handler_LS.locally_owned_dofs(),
989 * dof_handler_LS.locally_owned_dofs(),
990 * dsp, mpi_communicator);
991 * CTx_matrix.reinit (dof_handler_LS.locally_owned_dofs(),
992 * dof_handler_LS.locally_owned_dofs(),
993 * dsp, mpi_communicator);
994 * Cy_matrix.reinit (dof_handler_LS.locally_owned_dofs(),
995 * dof_handler_LS.locally_owned_dofs(),
996 * dsp, mpi_communicator);
997 * CTy_matrix.reinit (dof_handler_LS.locally_owned_dofs(),
998 * dof_handler_LS.locally_owned_dofs(),
999 * dsp, mpi_communicator);
1002 * Cz_matrix.reinit (dof_handler_LS.locally_owned_dofs(),
1003 * dof_handler_LS.locally_owned_dofs(),
1004 * dsp, mpi_communicator);
1005 * CTz_matrix.reinit (dof_handler_LS.locally_owned_dofs(),
1006 * dof_handler_LS.locally_owned_dofs(),
1007 * dsp, mpi_communicator);
1009 * dLij_matrix.reinit (dof_handler_LS.locally_owned_dofs(),
1010 * dof_handler_LS.locally_owned_dofs(),
1011 * dsp, mpi_communicator);
1012 * EntRes_matrix.reinit (dof_handler_LS.locally_owned_dofs(),
1013 * dof_handler_LS.locally_owned_dofs(),
1014 * dsp, mpi_communicator);
1015 * SuppSize_matrix.reinit (dof_handler_LS.locally_owned_dofs(),
1016 * dof_handler_LS.locally_owned_dofs(),
1017 * dsp, mpi_communicator);
1018 * dCij_matrix.reinit (dof_handler_LS.locally_owned_dofs(),
1019 * dof_handler_LS.locally_owned_dofs(),
1020 * dsp, mpi_communicator);
1021 * A_matrix.reinit (dof_handler_LS.locally_owned_dofs(),
1022 * dof_handler_LS.locally_owned_dofs(),
1023 * dsp, mpi_communicator);
1024 * LxA_matrix.reinit (dof_handler_LS.locally_owned_dofs(),
1025 * dof_handler_LS.locally_owned_dofs(),
1026 * dsp, mpi_communicator);
1027 * Akp1_matrix.reinit (dof_handler_LS.locally_owned_dofs(),
1028 * dof_handler_LS.locally_owned_dofs(),
1029 * dsp, mpi_communicator);
1030 * LxAkp1_matrix.reinit (dof_handler_LS.locally_owned_dofs(),
1031 * dof_handler_LS.locally_owned_dofs(),
1032 * dsp, mpi_communicator);
1035 * COMPUTE MASS MATRICES (AND OTHERS) FOR FIRST TIME STEP
1041 * assemble_C_Matrix();
1044 * get mat
for DOFs between Q1 and Q2
1047 * get_map_from_Q1_to_Q2();
1048 * get_sparsity_pattern();
1053 * ----------------------------------------------------------------------------
1054 * ------------------------------ MASS MATRICES ------------------------------
1055 * ----------------------------------------------------------------------------
1059 *
void LevelSetSolver<dim>::assemble_ML()
1063 *
const QGauss<dim> quadrature_formula(degree_MAX+1);
1069 *
const unsigned int dofs_per_cell = fe_LS.dofs_per_cell;
1070 *
const unsigned int n_q_points = quadrature_formula.size();
1073 * std::vector<types::global_dof_index> local_dof_indices (dofs_per_cell);
1076 * cell_LS = dof_handler_LS.begin_active(),
1077 * endc_LS = dof_handler_LS.end();
1079 *
for (; cell_LS!=endc_LS; ++cell_LS)
1080 *
if (cell_LS->is_locally_owned())
1083 * fe_values_LS.reinit (cell_LS);
1084 *
for (
unsigned int q_point=0; q_point<n_q_points; ++q_point)
1086 *
const double JxW = fe_values_LS.JxW(q_point);
1087 *
for (
unsigned int i=0; i<dofs_per_cell; ++i)
1088 * cell_ML (i) += fe_values_LS.shape_value(i,q_point)*JxW;
1095 * cell_LS->get_dof_indices (local_dof_indices);
1096 * constraints.distribute_local_to_global (cell_ML,local_dof_indices,ML_vector);
1107 *
void LevelSetSolver<dim>::invert_ML()
1111 *
loop on locally owned i-DOFs (rows)
1115 *
for (; idofs_iter!=locally_owned_dofs_LS.end(); ++idofs_iter)
1117 *
int gi = *idofs_iter;
1118 * inverse_ML_vector(gi) = 1./ML_vector(gi);
1124 *
void LevelSetSolver<dim>::assemble_MC()
1128 *
const QGauss<dim> quadrature_formula(degree_MAX+1);
1134 *
const unsigned int dofs_per_cell = fe_LS.dofs_per_cell;
1135 *
const unsigned int n_q_points = quadrature_formula.size();
1138 * std::vector<types::global_dof_index> local_dof_indices (dofs_per_cell);
1139 * std::vector<double> shape_values(dofs_per_cell);
1142 * cell_LS = dof_handler_LS.begin_active(),
1143 * endc_LS = dof_handler_LS.end();
1145 *
for (; cell_LS!=endc_LS; ++cell_LS)
1146 *
if (cell_LS->is_locally_owned())
1149 * fe_values_LS.reinit (cell_LS);
1150 *
for (
unsigned int q_point=0; q_point<n_q_points; ++q_point)
1152 *
const double JxW = fe_values_LS.JxW(q_point);
1153 *
for (
unsigned int i=0; i<dofs_per_cell; ++i)
1154 * shape_values[i] = fe_values_LS.shape_value(i,q_point);
1156 *
for (
unsigned int i=0; i<dofs_per_cell; ++i)
1157 *
for (
unsigned int j=0; j<dofs_per_cell; ++j)
1158 * cell_MC(i,j) += shape_values[i]*shape_values[j]*JxW;
1165 * cell_LS->get_dof_indices (local_dof_indices);
1166 * constraints.distribute_local_to_global (cell_MC,local_dof_indices,MC_matrix);
1179 * ---------------------------------------------------------------------------------------
1180 * ------------------------------
LO METHOD (Dij Viscosity) ------------------------------
1181 * ---------------------------------------------------------------------------------------
1184 *
template <
int dim>
1185 *
void LevelSetSolver<dim>::assemble_C_Matrix ()
1194 *
const QGauss<dim> quadrature_formula(degree_MAX+1);
1200 *
const unsigned int dofs_per_cell_LS = fe_LS.dofs_per_cell;
1201 *
const unsigned int n_q_points = quadrature_formula.size();
1210 * std::vector<Tensor<1, dim> > shape_grads_LS(dofs_per_cell_LS);
1211 * std::vector<double> shape_values_LS(dofs_per_cell_LS);
1213 * std::vector<types::global_dof_index> local_dof_indices_LS (dofs_per_cell_LS);
1216 * cell_LS = dof_handler_LS.begin_active();
1217 * endc_LS = dof_handler_LS.end();
1219 *
for (; cell_LS!=endc_LS; ++cell_LS)
1220 *
if (cell_LS->is_locally_owned())
1232 * fe_values_LS.reinit (cell_LS);
1233 * cell_LS->get_dof_indices (local_dof_indices_LS);
1235 *
for (
unsigned int q_point=0; q_point<n_q_points; ++q_point)
1237 *
const double JxW = fe_values_LS.JxW(q_point);
1238 *
for (
unsigned int i=0; i<dofs_per_cell_LS; ++i)
1240 * shape_values_LS[i] = fe_values_LS.shape_value(i,q_point);
1241 * shape_grads_LS [i] = fe_values_LS.shape_grad (i,q_point);
1244 *
for (
unsigned int i=0; i<dofs_per_cell_LS; ++i)
1245 *
for (
unsigned int j=0; j < dofs_per_cell_LS; ++j)
1247 * cell_Cij_x(i,j) += (shape_grads_LS[j][0])*shape_values_LS[i]*JxW;
1248 * cell_Cij_y(i,j) += (shape_grads_LS[j][1])*shape_values_LS[i]*JxW;
1249 * cell_Cji_x(i,j) += (shape_grads_LS[i][0])*shape_values_LS[j]*JxW;
1250 * cell_Cji_y(i,j) += (shape_grads_LS[i][1])*shape_values_LS[j]*JxW;
1253 * cell_Cij_z(i,j) += (shape_grads_LS[j][2])*shape_values_LS[i]*JxW;
1254 * cell_Cji_z(i,j) += (shape_grads_LS[i][2])*shape_values_LS[j]*JxW;
1263 * constraints.distribute_local_to_global(cell_Cij_x,local_dof_indices_LS,Cx_matrix);
1264 * constraints.distribute_local_to_global(cell_Cji_x,local_dof_indices_LS,CTx_matrix);
1265 * constraints.distribute_local_to_global(cell_Cij_y,local_dof_indices_LS,Cy_matrix);
1266 * constraints.distribute_local_to_global(cell_Cji_y,local_dof_indices_LS,CTy_matrix);
1269 * constraints.distribute_local_to_global(cell_Cij_z,local_dof_indices_LS,Cz_matrix);
1270 * constraints.distribute_local_to_global(cell_Cji_z,local_dof_indices_LS,CTz_matrix);
1292 * K_times_solution = 0;
1294 *
const QGauss<dim> quadrature_formula(degree_MAX+1);
1303 *
const unsigned int dofs_per_cell = fe_LS.dofs_per_cell;
1304 *
const unsigned int n_q_points = quadrature_formula.size();
1308 * std::vector<Tensor<1,dim> > un_grads (n_q_points);
1309 * std::vector<double> old_vx_values (n_q_points);
1310 * std::vector<double> old_vy_values (n_q_points);
1311 * std::vector<double> old_vz_values (n_q_points);
1313 * std::vector<double> shape_values(dofs_per_cell);
1314 * std::vector<Tensor<1,dim> > shape_grads(dofs_per_cell);
1318 * std::vector<types::global_dof_index> indices_LS (dofs_per_cell);
1326 * cell_LS = dof_handler_LS.begin_active(),
1327 * endc_LS = dof_handler_LS.end();
1329 * cell_U = dof_handler_U.begin_active();
1332 *
for (; cell_LS!=endc_LS; ++cell_U, ++cell_LS)
1333 *
if (cell_LS->is_locally_owned())
1335 * cell_K_times_solution=0;
1337 * fe_values_LS.reinit (cell_LS);
1338 * cell_LS->get_dof_indices (indices_LS);
1339 * fe_values_LS.get_function_gradients(solution,un_grads);
1341 * fe_values_U.reinit (cell_U);
1342 * fe_values_U.get_function_values(locally_relevant_solution_vx,old_vx_values);
1343 * fe_values_U.get_function_values(locally_relevant_solution_vy,old_vy_values);
1344 *
if (dim==3) fe_values_U.get_function_values(locally_relevant_solution_vz,old_vz_values);
1348 * compute cell_K_times_solution
1351 *
for (
unsigned int q_point=0; q_point<n_q_points; ++q_point)
1353 * v[0] = old_vx_values[q_point];
1354 * v[1] = old_vy_values[q_point];
1355 *
if (dim==3) v[2] = old_vz_values[q_point];
1357 *
for (
unsigned int i=0; i<dofs_per_cell; ++i)
1358 * cell_K_times_solution(i) += (v*un_grads[q_point])
1359 * *fe_values_LS.shape_value(i,q_point)*fe_values_LS.JxW(q_point);
1366 * constraints.distribute_local_to_global (cell_K_times_solution, indices_LS, K_times_solution);
1371 *
template <
int dim>
1372 *
void LevelSetSolver<dim>::assemble_K_DL_DH_times_vector
1377 * K_times_solution=0;
1380 * DL_times_solution=0;
1381 * DH_times_solution=0;
1385 * PetscInt ncolumns;
1386 *
const PetscInt *gj;
1387 *
const PetscScalar *Cxi, *Cyi, *Czi, *CTxi, *CTyi, *CTzi;
1388 *
const PetscScalar *EntResi, *SuppSizei, *MCi;
1395 *
loop on locally owned i-DOFs (rows)
1400 *
for (; idofs_iter!=locally_owned_dofs_LS.end(); ++idofs_iter)
1402 * PetscInt gi = *idofs_iter;
1405 *
double ith_K_times_solution = 0;
1409 * read velocity of i-th DOF
1412 * vi[0] = locally_relevant_solution_vx(map_from_Q1_to_Q2[gi]);
1413 * vi[1] = locally_relevant_solution_vy(map_from_Q1_to_Q2[gi]);
1414 *
if (dim==3) vi[2] = locally_relevant_solution_vz(map_from_Q1_to_Q2[gi]);
1415 * solni = solution(gi);
1419 * get i-th row of
C matrices
1422 * MatGetRow(Cx_matrix,gi,&ncolumns,&gj,&Cxi);
1423 * MatGetRow(Cy_matrix,gi,&ncolumns,&gj,&Cyi);
1424 * MatGetRow(CTx_matrix,gi,&ncolumns,&gj,&CTxi);
1425 * MatGetRow(CTy_matrix,gi,&ncolumns,&gj,&CTyi);
1428 * MatGetRow(Cz_matrix,gi,&ncolumns,&gj,&Czi);
1429 * MatGetRow(CTz_matrix,gi,&ncolumns,&gj,&CTzi);
1431 * MatGetRow(EntRes_matrix,gi,&ncolumns,&gj,&EntResi);
1432 * MatGetRow(SuppSize_matrix,gi,&ncolumns,&gj,&SuppSizei);
1433 * MatGetRow(MC_matrix,gi,&ncolumns,&gj,&MCi);
1437 * get vector values
for column indices
1440 *
const std::vector<types::global_dof_index> gj_indices (gj,gj+ncolumns);
1441 * std::vector<double> soln(ncolumns);
1442 * std::vector<double> vx(ncolumns);
1443 * std::vector<double> vy(ncolumns);
1444 * std::vector<double> vz(ncolumns);
1445 * get_vector_values(solution,gj_indices,soln);
1446 * get_vector_values(locally_relevant_solution_vx,gj_indices,map_from_Q1_to_Q2,vx);
1447 * get_vector_values(locally_relevant_solution_vy,gj_indices,map_from_Q1_to_Q2,vy);
1449 * get_vector_values(locally_relevant_solution_vz,gj_indices,map_from_Q1_to_Q2,vz);
1453 * Array
for i-th row of matrices
1456 * std::vector<double> dLi(ncolumns), dCi(ncolumns);
1457 *
double dLii = 0, dCii = 0;
1460 *
loop on sparsity pattern of i-th DOF
1463 *
for (
int j =0; j < ncolumns; ++j)
1480 * ith_K_times_solution += soln[j]*(vj*
C);
1487 * low order dissipative
matrix
1494 * high order dissipative
matrix (entropy viscosity)
1498 * cE*
std::abs(EntResi[j])/(entropy_normalization_factor*MCi[j]/SuppSizei[j]));
1501 * high order compression
matrix
1505 * dCi[j] = dEij*
std::max(1-Compij,0.0);
1511 * save
K times solution vector
1512 * K_times_solution(gi)=ith_K_times_solution;
1513 * save i-th row of matrices on global matrices
1516 * MatSetValuesRow(dLij_matrix,gi,&dLi[0]);
1517 * dLij_matrix.set(gi,gi,dLii);
1518 * MatSetValuesRow(dCij_matrix,gi,&dCi[0]);
1519 * dCij_matrix.set(gi,gi,dCii);
1523 * Restore matrices after reading rows
1526 * MatRestoreRow(Cx_matrix,gi,&ncolumns,&gj,&Cxi);
1527 * MatRestoreRow(Cy_matrix,gi,&ncolumns,&gj,&Cyi);
1528 * MatRestoreRow(CTx_matrix,gi,&ncolumns,&gj,&CTxi);
1529 * MatRestoreRow(CTy_matrix,gi,&ncolumns,&gj,&CTyi);
1532 * MatRestoreRow(Cz_matrix,gi,&ncolumns,&gj,&Czi);
1533 * MatRestoreRow(CTz_matrix,gi,&ncolumns,&gj,&CTzi);
1535 * MatRestoreRow(EntRes_matrix,gi,&ncolumns,&gj,&EntResi);
1536 * MatRestoreRow(SuppSize_matrix,gi,&ncolumns,&gj,&SuppSizei);
1537 * MatRestoreRow(MC_matrix,gi,&ncolumns,&gj,&MCi);
1549 * get matrices times vector
1552 * dLij_matrix.vmult(DL_times_solution,solution);
1553 * dCij_matrix.vmult(DH_times_solution,solution);
1558 * --------------------------------------------------------------------------------------
1559 * ------------------------------ ENTROPY VISCOSITY ------------------------------
1560 * --------------------------------------------------------------------------------------
1563 *
template <
int dim>
1564 *
void LevelSetSolver<dim>::assemble_EntRes_Matrix ()
1567 * entropy_normalization_factor=0;
1568 * SuppSize_matrix=0;
1570 *
const QGauss<dim> quadrature_formula(degree_MAX+1);
1580 *
const unsigned int dofs_per_cell_LS = fe_LS.dofs_per_cell;
1581 *
const unsigned int n_q_points = quadrature_formula.size();
1583 * std::vector<double> uqn (n_q_points);
1584 * std::vector<double> uqnm1 (n_q_points);
1585 * std::vector<Tensor<1,dim> > guqn (n_q_points);
1586 * std::vector<Tensor<1,dim> > guqnm1 (n_q_points);
1588 * std::vector<double> vxqn (n_q_points);
1589 * std::vector<double> vyqn (n_q_points);
1590 * std::vector<double> vzqn (n_q_points);
1591 * std::vector<double> vxqnm1 (n_q_points);
1592 * std::vector<double> vyqnm1 (n_q_points);
1593 * std::vector<double> vzqnm1 (n_q_points);
1598 * std::vector<Tensor<1, dim> > shape_grads_LS(dofs_per_cell_LS);
1599 * std::vector<double> shape_values_LS(dofs_per_cell_LS);
1601 * std::vector<types::global_dof_index> local_dof_indices_LS (dofs_per_cell_LS);
1604 * cell_LS = dof_handler_LS.begin_active();
1605 * endc_LS = dof_handler_LS.end();
1607 * cell_U = dof_handler_U.begin_active();
1610 *
double max_entropy=-1E10, min_entropy=1E10;
1611 *
double cell_max_entropy, cell_min_entropy;
1612 *
double cell_entropy_mass, entropy_mass=0;
1613 *
double cell_volume_double,
volume=0;
1615 *
for (; cell_LS!=endc_LS; ++cell_LS, ++cell_U)
1616 *
if (cell_LS->is_locally_owned())
1618 * cell_entropy_mass = 0;
1619 * cell_volume_double = 0;
1620 * cell_max_entropy = -1E10;
1621 * cell_min_entropy = 1E10;
1627 * get solutions at quadrature points
1630 * fe_values_LS.reinit(cell_LS);
1631 * cell_LS->get_dof_indices (local_dof_indices_LS);
1632 * fe_values_LS.get_function_values(un,uqn);
1633 * fe_values_LS.get_function_values(unm1,uqnm1);
1634 * fe_values_LS.get_function_gradients(un,guqn);
1635 * fe_values_LS.get_function_gradients(unm1,guqnm1);
1637 * fe_values_U.reinit(cell_U);
1638 * fe_values_U.get_function_values(locally_relevant_solution_vx,vxqn);
1639 * fe_values_U.get_function_values(locally_relevant_solution_vy,vyqn);
1640 *
if (dim==3) fe_values_U.get_function_values(locally_relevant_solution_vz,vzqn);
1641 * fe_values_U.get_function_values(locally_relevant_solution_vx_old,vxqnm1);
1642 * fe_values_U.get_function_values(locally_relevant_solution_vy_old,vyqnm1);
1643 *
if (dim==3) fe_values_U.get_function_values(locally_relevant_solution_vz_old,vzqnm1);
1645 *
for (
unsigned int q=0; q<n_q_points; ++q)
1647 * Rk = 1./time_step*(ENTROPY(uqn[q])-ENTROPY(uqnm1[q]))
1648 * +(vxqn[q]*ENTROPY_GRAD(uqn[q],guqn[q][0])+vyqn[q]*ENTROPY_GRAD(uqn[q],guqn[q][1]))/2.
1649 * +(vxqnm1[q]*ENTROPY_GRAD(uqnm1[q],guqnm1[q][0])+vyqnm1[q]*ENTROPY_GRAD(uqnm1[q],guqnm1[q][1]))/2.;
1651 * Rk += 0.5*(vzqn[q]*ENTROPY_GRAD(uqn[q],guqn[q][2])+vzqnm1[q]*ENTROPY_GRAD(uqnm1[q],guqnm1[q][2]));
1653 *
const double JxW = fe_values_LS.JxW(q);
1654 *
for (
unsigned int i=0; i<dofs_per_cell_LS; ++i)
1656 * shape_values_LS[i] = fe_values_LS.shape_value(i,q);
1657 * shape_grads_LS [i] = fe_values_LS.shape_grad (i,q);
1660 *
for (
unsigned int i=0; i<dofs_per_cell_LS; ++i)
1661 *
for (
unsigned int j=0; j < dofs_per_cell_LS; ++j)
1663 * cell_EntRes (i,j) += Rk*shape_values_LS[i]*shape_values_LS[j]*JxW;
1664 * cell_volume (i,j) += JxW;
1666 * cell_entropy_mass += ENTROPY(uqn[q])*JxW;
1667 * cell_volume_double += JxW;
1669 * cell_min_entropy =
std::min(cell_min_entropy,ENTROPY(uqn[q]));
1670 * cell_max_entropy =
std::max(cell_max_entropy,ENTROPY(uqn[q]));
1672 * entropy_mass += cell_entropy_mass;
1673 *
volume += cell_volume_double;
1675 * min_entropy =
std::min(min_entropy,cell_min_entropy);
1676 * max_entropy =
std::max(max_entropy,cell_max_entropy);
1682 * constraints.distribute_local_to_global(cell_EntRes,local_dof_indices_LS,EntRes_matrix);
1683 * constraints.distribute_local_to_global(cell_volume,local_dof_indices_LS,SuppSize_matrix);
1689 * ENTROPY NORM FACTOR
1701 * ------------------------------------------------------------------------------------
1702 * ------------------------------ TO CHECK MAX PRINCIPLE ------------------------------
1703 * ------------------------------------------------------------------------------------
1713 *
loop on locally owned i-DOFs (rows)
1717 *
for (; idofs_iter!=locally_owned_dofs_LS.end(); ++idofs_iter)
1719 *
int gi = *idofs_iter;
1723 * get solution at DOFs on the sparsity pattern of i-th DOF
1726 * std::vector<types::global_dof_index> gj_indices = sparsity_pattern[gi];
1727 * std::vector<double> soln(gj_indices.size());
1728 * get_vector_values(un_solution,gj_indices,soln);
1731 * compute bounds, ith row of flux
matrix, P vectors
1734 *
double mini=1E10, maxi=-1E10;
1735 *
for (
unsigned int j =0; j < gj_indices.size(); ++j)
1745 * umin_vector(gi) = mini;
1746 * umax_vector(gi) = maxi;
1757 * compute
min and
max vectors
1760 *
const unsigned int dofs_per_cell = fe_LS.dofs_per_cell;
1761 * std::vector<types::global_dof_index> local_dof_indices (dofs_per_cell);
1765 * cell_LS = dof_handler_LS.begin_active(),
1766 * endc_LS = dof_handler_LS.end();
1768 *
for (; cell_LS!=endc_LS; ++cell_LS)
1769 *
if (cell_LS->is_locally_owned() && !cell_LS->at_boundary())
1771 * cell_LS->get_dof_indices(local_dof_indices);
1772 *
for (
unsigned int i=0; i<dofs_per_cell; ++i)
1773 *
if (locally_owned_dofs_LS.is_element(local_dof_indices[i]))
1775 *
double solni = unp1_solution(local_dof_indices[i]);
1776 *
if (solni - umin_vector(local_dof_indices[i]) < -tol || umax_vector(local_dof_indices[i]) - solni < -tol)
1778 * pcout <<
"MAX Principle violated" << std::endl;
1787 * -------------------------------------------------------------------------------
1788 * ------------------------------ COMPUTE SOLUTIONS ------------------------------
1789 * -------------------------------------------------------------------------------
1793 *
void LevelSetSolver<dim>::compute_MPP_uL_and_NMPP_uH
1800 * NON-GHOSTED VECTORS: MPP_uL_solution, NMPP_uH_solution
1801 * GHOSTED VECTORS: un_solution
1804 * MPP_uL_solution=un_solution;
1805 * NMPP_uH_solution=un_solution;
1811 * assemble_K_times_vector(un_solution);
1812 * assemble_K_DL_DH_times_vector(un_solution);
1816 * COMPUTE MPP u1 solution
1820 * MPP_uL_solution.scale(ML_vector);
1821 * MPP_uL_solution.add(-time_step,K_times_solution);
1822 * MPP_uL_solution.add(-time_step,DL_times_solution);
1823 * MPP_uL_solution.scale(inverse_ML_vector);
1827 * COMPUTE GALERKIN u2 solution
1831 * MC_matrix.vmult(RHS,un_solution);
1832 * RHS.add(-time_step,K_times_solution,-time_step,DH_times_solution);
1833 * solve(constraints,MC_matrix,MC_preconditioner,NMPP_uH_solution,RHS);
1836 *
template <
int dim>
1837 *
void LevelSetSolver<dim>::compute_MPP_uH
1843 * MPP_uH_solution=0;
1846 *
loop on locally owned i-DOFs (rows)
1851 * PetscInt ncolumns;
1852 *
const PetscInt *gj;
1853 *
const PetscScalar *MCi, *dLi, *dCi;
1854 *
double solni, mi, solLi, solHi;
1856 *
for (; idofs_iter!=locally_owned_dofs_LS.end(); ++idofs_iter)
1858 *
int gi = *idofs_iter;
1861 * read vectors at i-th DOF
1864 * solni=solution(gi);
1865 * solHi=NMPP_uH_solution_ghosted(gi);
1866 * solLi=MPP_uL_solution_ghosted(gi);
1871 * get i-th row of matrices
1874 * MatGetRow(MC_matrix,gi,&ncolumns,&gj,&MCi);
1875 * MatGetRow(dLij_matrix,gi,&ncolumns,&gj,&dLi);
1876 * MatGetRow(dCij_matrix,gi,&ncolumns,&gj,&dCi);
1880 * get vector values
for support of i-th DOF
1883 *
const std::vector<types::global_dof_index> gj_indices (gj,gj+ncolumns);
1884 * std::vector<double> soln(ncolumns);
1885 * std::vector<double> solH(ncolumns);
1886 * get_vector_values(solution,gj_indices,soln);
1887 * get_vector_values(NMPP_uH_solution_ghosted,gj_indices,solH);
1891 * Array
for i-th row of matrices
1894 * std::vector<double> Ai(ncolumns);
1897 * compute bounds, ith row of flux
matrix, P vectors
1900 *
double mini=1E10, maxi=-1E10;
1901 *
double Pposi=0 ,Pnegi=0;
1902 *
for (
int j =0; j < ncolumns; ++j)
1917 * Ai[j] = (((gi==gj[j]) ? 1 : 0)*mi - MCi[j])*(solH[j]-soln[j] - (solHi-solni))
1918 * +time_step*(dLi[j]-dCi[j])*(soln[j]-solni);
1925 * Pposi += Ai[j]*((Ai[j] > 0) ? 1. : 0.);
1926 * Pnegi += Ai[j]*((Ai[j] < 0) ? 1. : 0.);
1930 * save i-th row of flux
matrix A
1933 * MatSetValuesRow(A_matrix,gi,&Ai[0]);
1940 *
double Qposi = mi*(maxi-solLi);
1941 *
double Qnegi = mi*(mini-solLi);
1948 * R_pos_vector_nonGhosted(gi) = ((Pposi==0) ? 1. :
std::min(1.0,Qposi/Pposi));
1949 * R_neg_vector_nonGhosted(gi) = ((Pnegi==0) ? 1. :
std::min(1.0,Qnegi/Pnegi));
1953 * Restore matrices after reading rows
1956 * MatRestoreRow(MC_matrix,gi,&ncolumns,&gj,&MCi);
1957 * MatRestoreRow(dLij_matrix,gi,&ncolumns,&gj,&dLi);
1958 * MatRestoreRow(dCij_matrix,gi,&ncolumns,&gj,&dCi);
1975 * update ghost values
for R vectors
1978 * R_pos_vector = R_pos_vector_nonGhosted;
1979 * R_neg_vector = R_neg_vector_nonGhosted;
1983 * compute limiters. NOTE:
this is a different
loop due to need of i- and j-th entries of R vectors
1987 *
double Rposi, Rnegi;
1988 * idofs_iter=locally_owned_dofs_LS.begin();
1989 *
for (; idofs_iter!=locally_owned_dofs_LS.end(); ++idofs_iter)
1991 *
int gi = *idofs_iter;
1992 * Rposi = R_pos_vector(gi);
1993 * Rnegi = R_neg_vector(gi);
2000 * MatGetRow(A_matrix,gi,&ncolumns,&gj,&Ai);
2004 * get vector values
for column indices
2007 *
const std::vector<types::global_dof_index> gj_indices (gj,gj+ncolumns);
2008 * std::vector<double> Rpos(ncolumns);
2009 * std::vector<double> Rneg(ncolumns);
2010 * get_vector_values(R_pos_vector,gj_indices,Rpos);
2011 * get_vector_values(R_neg_vector,gj_indices,Rneg);
2015 * Array
for i-th row of A_times_L
matrix
2018 * std::vector<double> LxAi(ncolumns);
2021 *
loop in sparsity pattern of i-th DOF
2024 *
for (
int j =0; j < ncolumns; ++j)
2025 * LxAi[j] = Ai[j] * ((Ai[j]>0) ?
std::min(Rposi,Rneg[j]) :
std::min(Rnegi,Rpos[j]));
2029 * save i-th row of LxA
2032 * MatSetValuesRow(LxA_matrix,gi,&LxAi[0]);
2035 * restore
A matrix after reading it
2038 * MatRestoreRow(A_matrix,gi,&ncolumns,&gj,&Ai);
2041 * LxA_matrix.vmult(MPP_uH_solution,ones_vector);
2042 * MPP_uH_solution.scale(inverse_ML_vector);
2043 * MPP_uH_solution.add(1.0,MPP_uL_solution_ghosted);
2047 *
void LevelSetSolver<dim>::compute_MPP_uH_with_iterated_FCT
2053 * MPP_uH_solution=0;
2054 * compute_MPP_uH(MPP_uH_solution,MPP_uL_solution_ghosted,NMPP_uH_solution_ghosted,un_solution);
2058 * Akp1_matrix.copy_from(A_matrix);
2059 * LxAkp1_matrix.copy_from(LxA_matrix);
2063 *
loop in num of FCT iterations
2066 * PetscInt ncolumns;
2067 *
const PetscInt *gj;
2068 *
const PetscScalar *Akp1i;
2070 *
for (
int iter=0; iter<NUM_ITER; ++iter)
2072 * MPP_uLkp1_solution_ghosted = MPP_uH_solution;
2073 * Akp1_matrix.add(-1.0, LxAkp1_matrix);
2077 *
loop on locally owned i-DOFs (rows)
2081 *
for (; idofs_iter!=locally_owned_dofs_LS.end(); ++idofs_iter)
2083 *
int gi = *idofs_iter;
2087 * read vectors at i-th DOF
2091 *
double solLi = MPP_uLkp1_solution_ghosted(gi);
2095 * get i-th row of matrices
2098 * MatGetRow(Akp1_matrix,gi,&ncolumns,&gj,&Akp1i);
2101 * get vector values
for support of i-th DOF
2104 *
const std::vector<types::global_dof_index> gj_indices (gj,gj+ncolumns);
2105 * std::vector<double> soln(ncolumns);
2106 * get_vector_values(un_solution,gj_indices,soln);
2110 * compute bounds, ith row of flux
matrix, P vectors
2113 *
double mini=1E10, maxi=-1E10;
2114 *
double Pposi=0 ,Pnegi=0;
2115 *
for (
int j =0; j < ncolumns; ++j)
2130 * Pposi += Akp1i[j]*((Akp1i[j] > 0) ? 1. : 0.);
2131 * Pnegi += Akp1i[j]*((Akp1i[j] < 0) ? 1. : 0.);
2138 *
double Qposi = mi*(maxi-solLi);
2139 *
double Qnegi = mi*(mini-solLi);
2146 * R_pos_vector_nonGhosted(gi) = ((Pposi==0) ? 1. :
std::min(1.0,Qposi/Pposi));
2147 * R_neg_vector_nonGhosted(gi) = ((Pnegi==0) ? 1. :
std::min(1.0,Qnegi/Pnegi));
2151 * Restore matrices after reading rows
2154 * MatRestoreRow(Akp1_matrix,gi,&ncolumns,&gj,&Akp1i);
2165 * update ghost values
for R vectors
2168 * R_pos_vector = R_pos_vector_nonGhosted;
2169 * R_neg_vector = R_neg_vector_nonGhosted;
2173 * compute limiters. NOTE:
this is a different
loop due to need of i- and j-th entries of R vectors
2176 *
double Rposi, Rnegi;
2177 * idofs_iter=locally_owned_dofs_LS.begin();
2178 *
for (; idofs_iter!=locally_owned_dofs_LS.end(); ++idofs_iter)
2180 *
int gi = *idofs_iter;
2181 * Rposi = R_pos_vector(gi);
2182 * Rnegi = R_neg_vector(gi);
2186 * get i-th row of Akp1
matrix
2189 * MatGetRow(Akp1_matrix,gi,&ncolumns,&gj,&Akp1i);
2193 * get vector values
for column indices
2196 *
const std::vector<types::global_dof_index> gj_indices(gj,gj+ncolumns);
2197 * std::vector<double> Rpos(ncolumns);
2198 * std::vector<double> Rneg(ncolumns);
2199 * get_vector_values(R_pos_vector,gj_indices,Rpos);
2200 * get_vector_values(R_neg_vector,gj_indices,Rneg);
2204 * Array
for i-th row of LxAkp1
matrix
2207 * std::vector<double> LxAkp1i(ncolumns);
2208 *
for (
int j =0; j < ncolumns; ++j)
2209 * LxAkp1i[j] = Akp1i[j] * ((Akp1i[j]>0) ?
std::min(Rposi,Rneg[j]) :
std::min(Rnegi,Rpos[j]));
2213 * save i-th row of LxA
2216 * MatSetValuesRow(LxAkp1_matrix,gi,&LxAkp1i[0]);
2219 * restore
A matrix after reading it
2222 * MatRestoreRow(Akp1_matrix,gi,&ncolumns,&gj,&Akp1i);
2225 * LxAkp1_matrix.vmult(MPP_uH_solution,ones_vector);
2226 * MPP_uH_solution.scale(inverse_ML_vector);
2227 * MPP_uH_solution.add(1.0,MPP_uLkp1_solution_ghosted);
2235 * std::string algorithm)
2240 * COMPUTE MPP LOW-ORDER SOLN and NMPP HIGH-ORDER SOLN
2243 * compute_MPP_uL_and_NMPP_uH(MPP_uL_solution,NMPP_uH_solution,un);
2245 *
if (algorithm.compare(
"MPP_u1")==0)
2246 * unp1=MPP_uL_solution;
2247 *
else if (algorithm.compare(
"NMPP_uH")==0)
2248 * unp1=NMPP_uH_solution;
2249 *
else if (algorithm.compare(
"MPP_uH")==0)
2251 * MPP_uL_solution_ghosted = MPP_uL_solution;
2252 * NMPP_uH_solution_ghosted=NMPP_uH_solution;
2253 * compute_MPP_uH_with_iterated_FCT(MPP_uH_solution,MPP_uL_solution_ghosted,NMPP_uH_solution_ghosted,un);
2254 * unp1=MPP_uH_solution;
2258 * pcout <<
"Error in algorithm" << std::endl;
2266 * std::string algorithm)
2270 * GHOSTED VECTORS: un
2271 * NON-GHOSTED VECTORS: unp1
2275 * uStage1=0., uStage2=0.;
2276 * uStage1_nonGhosted=0., uStage2_nonGhosted=0.;
2285 * compute_solution(uStage1_nonGhosted,un,algorithm);
2286 * uStage1=uStage1_nonGhosted;
2292 * u2=3/4*un+1/4*(u1-dt*RH*u1)
2295 * compute_solution(uStage2_nonGhosted,uStage1,algorithm);
2296 * uStage2_nonGhosted*=1./4;
2297 * uStage2_nonGhosted.add(3./4,un);
2298 * uStage2=uStage2_nonGhosted;
2304 * unp1=1/3*un+2/3*(u2-dt*RH*u2)
2307 * compute_solution(unp1,uStage2,algorithm);
2309 * unp1.add(1./3,un);
2314 * -----------------------------------------------------------------------
2315 * ------------------------------ UTILITIES ------------------------------
2316 * -----------------------------------------------------------------------
2320 *
void LevelSetSolver<dim>::get_sparsity_pattern()
2328 * PetscInt ncolumns;
2329 *
const PetscInt *gj;
2330 *
const PetscScalar *MCi;
2332 *
for (; idofs_iter!=locally_owned_dofs_LS.end(); ++idofs_iter)
2334 * PetscInt gi = *idofs_iter;
2337 * get i-th row of mass
matrix (dummy, I just need the indices gj)
2340 * MatGetRow(MC_matrix,gi,&ncolumns,&gj,&MCi);
2341 * sparsity_pattern[gi] = std::vector<types::global_dof_index>(gj,gj+ncolumns);
2342 * MatRestoreRow(MC_matrix,gi,&ncolumns,&gj,&MCi);
2347 *
void LevelSetSolver<dim>::get_map_from_Q1_to_Q2()
2349 * map_from_Q1_to_Q2.clear();
2350 *
const unsigned int dofs_per_cell_LS = fe_LS.dofs_per_cell;
2351 * std::vector<types::global_dof_index> local_dof_indices_LS (dofs_per_cell_LS);
2352 *
const unsigned int dofs_per_cell_U = fe_U.dofs_per_cell;
2353 * std::vector<types::global_dof_index> local_dof_indices_U (dofs_per_cell_U);
2356 * cell_LS = dof_handler_LS.begin_active(),
2357 * endc_LS = dof_handler_LS.end();
2359 * cell_U = dof_handler_U.begin_active();
2361 *
for (; cell_LS!=endc_LS; ++cell_LS, ++cell_U)
2362 *
if (!cell_LS->is_artificial())
2364 * cell_LS->get_dof_indices(local_dof_indices_LS);
2365 * cell_U->get_dof_indices(local_dof_indices_U);
2366 *
for (
unsigned int i=0; i<dofs_per_cell_LS; ++i)
2367 * map_from_Q1_to_Q2[local_dof_indices_LS[i]] = local_dof_indices_U[i];
2371 *
template <
int dim>
2374 * std::shared_ptr<PETScWrappers::PreconditionBoomerAMG> preconditioner,
2380 * all vectors are NON-GHOSTED
2383 *
SolverControl solver_control (dof_handler_LS.n_dofs(), solver_tolerance);
2385 * constraints.distribute (completely_distributed_solution);
2386 * solver.solve (Matrix, completely_distributed_solution, rhs, *preconditioner);
2387 * constraints.distribute (completely_distributed_solution);
2388 *
if (verbose==
true) pcout <<
" Solved in " << solver_control.last_step() <<
" iterations." << std::endl;
2391 *
template <
int dim>
2392 *
void LevelSetSolver<dim>::save_old_solution()
2398 *
template <
int dim>
2399 *
void LevelSetSolver<dim>::save_old_vel_solution()
2401 * locally_relevant_solution_vx_old = locally_relevant_solution_vx;
2402 * locally_relevant_solution_vy_old = locally_relevant_solution_vy;
2404 * locally_relevant_solution_vz_old = locally_relevant_solution_vz;
2409 * -------------------------------------------------------------------------------
2410 * ------------------------------ MY PETSC WRAPPERS ------------------------------
2411 * -------------------------------------------------------------------------------
2416 *
const std::vector<types::global_dof_index> &indices,
2417 * std::vector<PetscScalar> &values)
2421 *
PETSc wrapper to get sets of values from a petsc vector.
2422 * we assume the vector is ghosted
2423 * We need to figure out which elements we
2424 * own locally. Then get a pointer to the
2425 * elements that are stored here (both the
2426 * ones we own as well as the ghost elements).
2427 * In
this array, the locally owned elements
2428 * come first followed by the ghost elements whose
2429 * position we can get from an
index set
2435 *
IndexSet ghost_indices = locally_relevant_dofs_LS;
2439 * n_idx = indices.size();
2441 * VecGetOwnershipRange (vector, &begin, &end);
2443 * Vec solution_in_local_form =
nullptr;
2444 * VecGhostGetLocalForm(vector, &solution_in_local_form);
2446 * PetscScalar *soln;
2447 * VecGetArray(solution_in_local_form, &soln);
2449 *
for (i = 0; i < n_idx; ++i)
2451 *
int index = indices[i];
2452 *
if (index >= begin && index < end)
2456 *
const unsigned int ghostidx = ghost_indices.index_within_set(index);
2457 * values[i] = *(soln+ghostidx+
end-
begin);
2460 * VecRestoreArray(solution_in_local_form, &soln);
2461 * VecGhostRestoreLocalForm(vector, &solution_in_local_form);
2466 *
const std::vector<types::global_dof_index> &indices,
2467 * std::map<types::global_dof_index, types::global_dof_index> &map_from_Q1_to_Q2,
2468 * std::vector<PetscScalar> &values)
2472 * THIS IS MEANT TO BE USED WITH VELOCITY VECTORS
2473 *
PETSc wrapper to get sets of values from a petsc vector.
2474 * we assume the vector is ghosted
2475 * We need to figure out which elements we
2476 * own locally. Then get a pointer to the
2477 * elements that are stored here (both the
2478 * ones we own as well as the ghost elements).
2479 * In
this array, the locally owned elements
2480 * come first followed by the ghost elements whose
2481 * position we can get from an
index set
2487 *
IndexSet ghost_indices = locally_relevant_dofs_U;
2491 * n_idx = indices.size();
2493 * VecGetOwnershipRange (vector, &begin, &end);
2495 * Vec solution_in_local_form =
nullptr;
2496 * VecGhostGetLocalForm(vector, &solution_in_local_form);
2498 * PetscScalar *soln;
2499 * VecGetArray(solution_in_local_form, &soln);
2501 *
for (i = 0; i < n_idx; ++i)
2503 *
int index = map_from_Q1_to_Q2[indices[i]];
2504 *
if (index >= begin && index < end)
2508 *
const unsigned int ghostidx = ghost_indices.index_within_set(index);
2509 * values[i] = *(soln+ghostidx+
end-
begin);
2512 * VecRestoreArray(solution_in_local_form, &soln);
2513 * VecGhostRestoreLocalForm(vector, &solution_in_local_form);
2519<a name=
"ann-MultiPhase.cc"></a>
2520<h1>Annotated version of MultiPhase.cc</h1>
2536 * #include <deal.II/base/quadrature_lib.h>
2537 * #include <deal.II/base/function.h>
2538 * #include <deal.II/lac/affine_constraints.h>
2539 * #include <deal.II/lac/vector.h>
2540 * #include <deal.II/lac/full_matrix.h>
2541 * #include <deal.II/lac/solver_cg.h>
2542 * #include <deal.II/lac/petsc_sparse_matrix.h>
2543 * #include <deal.II/lac/petsc_vector.h>
2544 * #include <deal.II/lac/petsc_solver.h>
2545 * #include <deal.II/lac/petsc_precondition.h>
2546 * #include <deal.II/grid/grid_generator.h>
2547 * #include <deal.II/grid/tria_accessor.h>
2548 * #include <deal.II/grid/tria_iterator.h>
2549 * #include <deal.II/dofs/dof_handler.h>
2550 * #include <deal.II/dofs/dof_accessor.h>
2551 * #include <deal.II/dofs/dof_tools.h>
2552 * #include <deal.II/fe/fe_values.h>
2553 * #include <deal.II/fe/fe_q.h>
2554 * #include <deal.II/numerics/vector_tools.h>
2555 * #include <deal.II/numerics/data_out.h>
2556 * #include <deal.II/numerics/error_estimator.h>
2557 * #include <deal.II/base/utilities.h>
2558 * #include <deal.II/base/conditional_ostream.h>
2559 * #include <deal.II/base/index_set.h>
2560 * #include <deal.II/lac/sparsity_tools.h>
2561 * #include <deal.II/distributed/tria.h>
2562 * #include <deal.II/distributed/grid_refinement.h>
2563 * #include <deal.II/base/convergence_table.h>
2564 * #include <deal.II/base/timer.h>
2565 * #include <deal.II/base/parameter_handler.h>
2566 * #include <fstream>
2567 * #include <iostream>
2568 * #include <deal.II/grid/grid_tools.h>
2569 * #include <deal.II/fe/mapping_q.h>
2571 *
using namespace dealii;
2576 * FOR TRANSPORT PROBLEM
2588 * #define FILLING_TANK 0
2589 * #define BREAKING_DAM 1
2590 * #define FALLING_DROP 2
2591 * #define SMALL_WAVE_PERTURBATION 3
2593 * #include
"NavierStokesSolver.cc"
2594 * #include
"LevelSetSolver.cc"
2595 * #include
"utilities.cc"
2604 *
template <
int dim>
2608 * MultiPhase (
const unsigned int degree_LS,
2609 *
const unsigned int degree_U);
2614 *
void set_boundary_inlet();
2615 *
void get_boundary_values_U();
2616 *
void get_boundary_values_phi(std::vector<types::global_dof_index> &boundary_values_id_phi,
2617 * std::vector<double> &boundary_values_phi);
2618 *
void output_results();
2619 *
void output_vectors();
2620 *
void output_rho();
2622 *
void initial_condition();
2623 *
void init_constraints();
2632 *
IndexSet locally_relevant_dofs_LS;
2639 *
IndexSet locally_relevant_dofs_U;
2644 *
IndexSet locally_relevant_dofs_P;
2666 * std::vector<types::global_dof_index> boundary_values_id_u;
2667 * std::vector<types::global_dof_index> boundary_values_id_v;
2668 * std::vector<types::global_dof_index> boundary_values_id_phi;
2669 * std::vector<double> boundary_values_u;
2670 * std::vector<double> boundary_values_v;
2671 * std::vector<double> boundary_values_phi;
2677 *
double final_time;
2678 *
unsigned int timestep_number;
2684 *
int sharpness_integer;
2686 *
unsigned int n_refinement;
2687 *
unsigned int output_number;
2688 *
double output_time;
2712 *
unsigned int TRANSPORT_TIME_INTEGRATION;
2713 * std::string ALGORITHM;
2714 *
unsigned int PROBLEM;
2717 *
template <
int dim>
2718 * MultiPhase<dim>::MultiPhase (
const unsigned int degree_LS,
2719 *
const unsigned int degree_U)
2721 * mpi_communicator (MPI_COMM_WORLD),
2722 * triangulation (mpi_communicator,
2726 * degree_LS(degree_LS),
2727 * dof_handler_LS (triangulation),
2728 * fe_LS (degree_LS),
2729 * degree_U(degree_U),
2730 * dof_handler_U (triangulation),
2732 * dof_handler_P (triangulation),
2733 * fe_P (degree_U-1),
2737 *
template <
int dim>
2738 * MultiPhase<dim>::~MultiPhase ()
2740 * dof_handler_LS.clear ();
2741 * dof_handler_U.clear ();
2742 * dof_handler_P.clear ();
2752 *
template <
int dim>
2753 *
void MultiPhase<dim>::setup()
2760 * dof_handler_LS.distribute_dofs (fe_LS);
2761 * locally_owned_dofs_LS = dof_handler_LS.locally_owned_dofs ();
2768 * dof_handler_U.distribute_dofs (fe_U);
2769 * locally_owned_dofs_U = dof_handler_U.locally_owned_dofs ();
2776 * dof_handler_P.distribute_dofs (fe_P);
2777 * locally_owned_dofs_P = dof_handler_P.locally_owned_dofs ();
2781 * init vectors
for phi
2784 * locally_relevant_solution_phi.reinit(locally_owned_dofs_LS,locally_relevant_dofs_LS,mpi_communicator);
2785 * locally_relevant_solution_phi = 0;
2786 * completely_distributed_solution_phi.reinit (locally_owned_dofs_P,mpi_communicator);
2789 * init vectors
for u
2792 * locally_relevant_solution_u.reinit (locally_owned_dofs_U,locally_relevant_dofs_U,mpi_communicator);
2793 * locally_relevant_solution_u = 0;
2794 * completely_distributed_solution_u.reinit (locally_owned_dofs_U,mpi_communicator);
2797 * init vectors
for v
2800 * locally_relevant_solution_v.reinit (locally_owned_dofs_U,locally_relevant_dofs_U,mpi_communicator);
2801 * locally_relevant_solution_v = 0;
2802 * completely_distributed_solution_v.reinit (locally_owned_dofs_U,mpi_communicator);
2805 * init vectors
for p
2808 * locally_relevant_solution_p.reinit (locally_owned_dofs_P,locally_relevant_dofs_P,mpi_communicator);
2809 * locally_relevant_solution_p = 0;
2810 * completely_distributed_solution_p.reinit (locally_owned_dofs_P,mpi_communicator);
2816 * init_constraints();
2819 *
template <
int dim>
2820 *
void MultiPhase<dim>::initial_condition()
2825 * Initial conditions
2826 * init condition
for phi
2829 * completely_distributed_solution_phi = 0;
2831 * InitialPhi<dim>(PROBLEM, sharpness),
2832 * completely_distributed_solution_phi);
2833 * constraints.distribute (completely_distributed_solution_phi);
2834 * locally_relevant_solution_phi = completely_distributed_solution_phi;
2837 * init condition
for u=0
2840 * completely_distributed_solution_u = 0;
2843 * completely_distributed_solution_u);
2844 * constraints.distribute (completely_distributed_solution_u);
2845 * locally_relevant_solution_u = completely_distributed_solution_u;
2848 * init condition
for v
2851 * completely_distributed_solution_v = 0;
2854 * completely_distributed_solution_v);
2855 * constraints.distribute (completely_distributed_solution_v);
2856 * locally_relevant_solution_v = completely_distributed_solution_v;
2859 * init condition
for p
2862 * completely_distributed_solution_p = 0;
2865 * completely_distributed_solution_p);
2866 * constraints.distribute (completely_distributed_solution_p);
2867 * locally_relevant_solution_p = completely_distributed_solution_p;
2870 *
template <
int dim>
2871 *
void MultiPhase<dim>::init_constraints()
2873 * constraints.clear ();
2875 * constraints.reinit (locally_owned_dofs_LS, locally_relevant_dofs_LS);
2877 * constraints.reinit (locally_relevant_dofs_LS);
2880 * constraints.close ();
2883 *
template <
int dim>
2884 *
void MultiPhase<dim>::get_boundary_values_U()
2886 * std::map<types::global_dof_index, double> map_boundary_values_u;
2887 * std::map<types::global_dof_index, double> map_boundary_values_v;
2888 * std::map<types::global_dof_index, double> map_boundary_values_w;
2895 *
if (PROBLEM==BREAKING_DAM || PROBLEM==FALLING_DROP)
2926 *
else if (PROBLEM==SMALL_WAVE_PERTURBATION)
2930 * no slip in bottom and top and slip in left and right
2956 *
else if (PROBLEM==FILLING_TANK)
2960 * LEFT: entry in x,
zero in y
2967 * RIGHT: no-slip condition
2981 * TOP: exit in y,
zero in x
2989 * pcout <<
"Error in type of PROBLEM at Boundary Conditions" << std::endl;
2992 * boundary_values_id_u.resize(map_boundary_values_u.size());
2993 * boundary_values_id_v.resize(map_boundary_values_v.size());
2994 * boundary_values_u.resize(map_boundary_values_u.size());
2995 * boundary_values_v.resize(map_boundary_values_v.size());
2996 * std::map<types::global_dof_index,double>::const_iterator boundary_value_u =map_boundary_values_u.begin();
2997 * std::map<types::global_dof_index,double>::const_iterator boundary_value_v =map_boundary_values_v.begin();
2999 *
for (
int i=0; boundary_value_u !=map_boundary_values_u.end(); ++boundary_value_u, ++i)
3001 * boundary_values_id_u[i]=boundary_value_u->first;
3002 * boundary_values_u[i]=boundary_value_u->second;
3004 *
for (
int i=0; boundary_value_v !=map_boundary_values_v.end(); ++boundary_value_v, ++i)
3006 * boundary_values_id_v[i]=boundary_value_v->first;
3007 * boundary_values_v[i]=boundary_value_v->second;
3011 *
template <
int dim>
3012 *
void MultiPhase<dim>::set_boundary_inlet()
3014 *
const QGauss<dim-1> face_quadrature_formula(1);
3018 *
const unsigned int n_face_q_points = face_quadrature_formula.size();
3019 * std::vector<double> u_value (n_face_q_points);
3020 * std::vector<double> v_value (n_face_q_points);
3023 * cell_U = dof_handler_U.begin_active(),
3024 * endc_U = dof_handler_U.end();
3027 *
for (; cell_U!=endc_U; ++cell_U)
3028 *
if (cell_U->is_locally_owned())
3029 *
for (
unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
3030 *
if (cell_U->face(face)->at_boundary())
3032 * fe_face_values.reinit(cell_U,face);
3033 * fe_face_values.get_function_values(locally_relevant_solution_u,u_value);
3034 * fe_face_values.get_function_values(locally_relevant_solution_v,v_value);
3037 *
if (fe_face_values.normal_vector(0)*u < -1e-14)
3038 * cell_U->face(face)->set_boundary_id(10);
3042 *
template <
int dim>
3043 *
void MultiPhase<dim>::get_boundary_values_phi(std::vector<types::global_dof_index> &boundary_values_id_phi,
3044 * std::vector<double> &boundary_values_phi)
3046 * std::map<types::global_dof_index, double> map_boundary_values_phi;
3049 * set_boundary_inlet();
3052 * boundary_values_id_phi.resize(map_boundary_values_phi.size());
3053 * boundary_values_phi.resize(map_boundary_values_phi.size());
3054 * std::map<types::global_dof_index,double>::const_iterator boundary_value_phi = map_boundary_values_phi.begin();
3055 *
for (
int i=0; boundary_value_phi !=map_boundary_values_phi.end(); ++boundary_value_phi, ++i)
3057 * boundary_values_id_phi[i]=boundary_value_phi->first;
3058 * boundary_values_phi[i]=boundary_value_phi->second;
3063 *
void MultiPhase<dim>::output_results()
3074 *
template <
int dim>
3075 *
void MultiPhase<dim>::output_vectors()
3079 * data_out.add_data_vector (locally_relevant_solution_phi,
"phi");
3080 * data_out.build_patches ();
3082 *
const std::string filename = (
"sol_vectors-" +
3086 * (triangulation.locally_owned_subdomain(), 4));
3087 * std::ofstream output ((filename +
".vtu").c_str());
3088 * data_out.write_vtu (output);
3092 * std::vector<std::string> filenames;
3093 *
for (
unsigned int i=0;
3096 * filenames.push_back (
"sol_vectors-" +
3102 * std::ofstream master_output ((filename +
".pvtu").c_str());
3103 * data_out.write_pvtu_record (master_output, filenames);
3107 *
template <
int dim>
3108 *
void MultiPhase<dim>::output_rho()
3110 * Postprocessor<dim> postprocessor(eps,rho_air,rho_fluid);
3113 * data_out.add_data_vector (locally_relevant_solution_phi, postprocessor);
3115 * data_out.build_patches ();
3117 *
const std::string filename = (
"sol_rho-" +
3121 * (triangulation.locally_owned_subdomain(), 4));
3122 * std::ofstream output ((filename +
".vtu").c_str());
3123 * data_out.write_vtu (output);
3127 * std::vector<std::string> filenames;
3128 *
for (
unsigned int i=0;
3131 * filenames.push_back (
"sol_rho-" +
3137 * std::ofstream master_output ((filename +
".pvtu").c_str());
3138 * data_out.write_pvtu_record (master_output, filenames);
3142 *
template <
int dim>
3143 *
void MultiPhase<dim>::run()
3148 * GENERAL PARAMETERS
3155 * get_output =
true;
3156 * output_number = 0;
3158 * output_time = 0.1;
3159 * final_time = 10.0;
3163 * PARAMETERS FOR THE NAVIER STOKES PROBLEM
3167 * rho_fluid = 1000.;
3171 * PROBLEM=BREAKING_DAM;
3174 * PROBLEM=FILLING_TANK;
3175 * PROBLEM=SMALL_WAVE_PERTURBATION;
3176 * PROBLEM=FALLING_DROP;
3182 * ForceTerms<dim> force_function(std::vector<double> {0.0,-1.0});
3186 * PARAMETERS FOR TRANSPORT PROBLEM
3192 * sharpness_integer=10;
3198 * TRANSPORT_TIME_INTEGRATION=SSP33;
3201 * ALGORITHM =
"MPP_u1";
3202 * ALGORITHM =
"NMPP_uH";
3205 * ALGORITHM =
"MPP_uH";
3209 * ADJUST PARAMETERS ACCORDING TO PROBLEM
3212 *
if (PROBLEM==FALLING_DROP)
3222 *
if (PROBLEM==FILLING_TANK)
3225 *
else if (PROBLEM==BREAKING_DAM || PROBLEM==SMALL_WAVE_PERTURBATION)
3227 * std::vector< unsigned int > repetitions;
3228 * repetitions.push_back(2);
3229 * repetitions.push_back(1);
3233 *
else if (PROBLEM==FALLING_DROP)
3235 * std::vector< unsigned int > repetitions;
3236 * repetitions.push_back(1);
3237 * repetitions.push_back(4);
3241 * triangulation.refine_global (n_refinement);
3251 * PARAMETERS FOR TIME STEPPING
3255 * time_step = cfl*min_h/umax;
3257 * sharpness=sharpness_integer*min_h;
3261 * INITIAL CONDITIONS
3264 * initial_condition();
3269 * NAVIER STOKES SOLVER
3272 * NavierStokesSolver<dim> navier_stokes (degree_LS,degree_U,
3275 * rho_fluid,nu_fluid,
3278 * triangulation,mpi_communicator);
3281 * BOUNDARY CONDITIONS FOR NAVIER STOKES
3284 * get_boundary_values_U();
3285 * navier_stokes.set_boundary_conditions(boundary_values_id_u, boundary_values_id_v,
3286 * boundary_values_u, boundary_values_v);
3290 * set INITIAL CONDITION within NAVIER STOKES
3293 * navier_stokes.initial_condition(locally_relevant_solution_phi,
3294 * locally_relevant_solution_u,
3295 * locally_relevant_solution_v,
3296 * locally_relevant_solution_p);
3302 * LevelSetSolver<dim> transport_solver (degree_LS,degree_U,
3306 * TRANSPORT_TIME_INTEGRATION,
3308 * mpi_communicator);
3311 * BOUNDARY CONDITIONS FOR PHI
3314 * get_boundary_values_phi(boundary_values_id_phi,boundary_values_phi);
3315 * transport_solver.set_boundary_conditions(boundary_values_id_phi,boundary_values_phi);
3319 * set INITIAL CONDITION within TRANSPORT PROBLEM
3322 * transport_solver.initial_condition(locally_relevant_solution_phi,
3323 * locally_relevant_solution_u,
3324 * locally_relevant_solution_v);
3325 *
int dofs_U = 2*dof_handler_U.n_dofs();
3326 *
int dofs_P = 2*dof_handler_P.n_dofs();
3327 *
int dofs_LS = dof_handler_LS.n_dofs();
3328 *
int dofs_TOTAL = dofs_U+dofs_P+dofs_LS;
3332 * NO BOUNDARY CONDITIONS
for LEVEL SET
3335 * pcout <<
"Cfl: " << cfl <<
"; umax: " << umax <<
"; min h: " << min_h
3336 * <<
"; time step: " << time_step << std::endl;
3337 * pcout <<
" Number of active cells: "
3338 * << triangulation.n_global_active_cells() << std::endl
3339 * <<
" Number of degrees of freedom: " << std::endl
3340 * <<
" U: " << dofs_U << std::endl
3341 * <<
" P: " << dofs_P << std::endl
3342 * <<
" LS: " << dofs_LS << std::endl
3343 * <<
" TOTAL: " << dofs_TOTAL
3351 *
for (timestep_number=1, time=time_step; time<=final_time;
3352 * time+=time_step,++timestep_number)
3354 * pcout <<
"Time step " << timestep_number
3355 * <<
" at t=" << time
3359 * GET NAVIER STOKES VELOCITY
3362 * navier_stokes.set_phi(locally_relevant_solution_phi);
3363 * navier_stokes.nth_time_step();
3364 * navier_stokes.get_velocity(locally_relevant_solution_u,locally_relevant_solution_v);
3365 * transport_solver.set_velocity(locally_relevant_solution_u,locally_relevant_solution_v);
3368 * GET LEVEL SET SOLUTION
3371 * transport_solver.nth_time_step();
3372 * transport_solver.get_unp1(locally_relevant_solution_phi);
3373 *
if (get_output && time-(output_number)*output_time>0)
3376 * navier_stokes.get_velocity(locally_relevant_solution_u, locally_relevant_solution_v);
3377 * transport_solver.get_unp1(locally_relevant_solution_phi);
3382 *
int main(
int argc,
char *argv[])
3386 *
using namespace dealii;
3390 *
unsigned int degree_LS = 1;
3391 *
unsigned int degree_U = 2;
3392 * MultiPhase<2> multi_phase(degree_LS, degree_U);
3393 * multi_phase.run();
3397 *
catch (std::exception &exc)
3399 * std::cerr << std::endl << std::endl
3400 * <<
"----------------------------------------------------"
3402 * std::cerr <<
"Exception on processing: " << std::endl
3403 * << exc.what() << std::endl
3404 * <<
"Aborting!" << std::endl
3405 * <<
"----------------------------------------------------"
3411 * std::cerr << std::endl << std::endl
3412 * <<
"----------------------------------------------------"
3414 * std::cerr <<
"Unknown exception!" << std::endl
3415 * <<
"Aborting!" << std::endl
3416 * <<
"----------------------------------------------------"
3425<a name=
"ann-NavierStokesSolver.cc"></a>
3426<h1>Annotated version of NavierStokesSolver.cc</h1>
3442 * #include <deal.II/base/quadrature_lib.h>
3443 * #include <deal.II/base/function.h>
3444 * #include <deal.II/lac/affine_constraints.h>
3445 * #include <deal.II/lac/vector.h>
3446 * #include <deal.II/lac/full_matrix.h>
3447 * #include <deal.II/lac/solver_cg.h>
3448 * #include <deal.II/lac/petsc_sparse_matrix.h>
3449 * #include <deal.II/lac/petsc_vector.h>
3450 * #include <deal.II/lac/petsc_solver.h>
3451 * #include <deal.II/lac/petsc_precondition.h>
3452 * #include <deal.II/grid/grid_generator.h>
3453 * #include <deal.II/grid/tria_accessor.h>
3454 * #include <deal.II/grid/tria_iterator.h>
3455 * #include <deal.II/dofs/dof_handler.h>
3456 * #include <deal.II/dofs/dof_accessor.h>
3457 * #include <deal.II/dofs/dof_tools.h>
3458 * #include <deal.II/fe/fe_values.h>
3459 * #include <deal.II/fe/fe_q.h>
3460 * #include <deal.II/numerics/vector_tools.h>
3461 * #include <deal.II/numerics/data_out.h>
3462 * #include <deal.II/numerics/error_estimator.h>
3463 * #include <deal.II/base/utilities.h>
3464 * #include <deal.II/base/conditional_ostream.h>
3465 * #include <deal.II/base/index_set.h>
3466 * #include <deal.II/lac/sparsity_tools.h>
3467 * #include <deal.II/distributed/tria.h>
3468 * #include <deal.II/distributed/grid_refinement.h>
3469 * #include <deal.II/lac/petsc_vector.h>
3470 * #include <deal.II/base/convergence_table.h>
3471 * #include <deal.II/base/timer.h>
3472 * #include <deal.II/base/parameter_handler.h>
3473 * #include <deal.II/grid/grid_tools.h>
3474 * #include <deal.II/fe/mapping_q.h>
3476 * #include <fstream>
3477 * #include <iostream>
3480 *
using namespace dealii;
3482 * #define MAX_NUM_ITER_TO_RECOMPUTE_PRECONDITIONER 10
3492 *
class NavierStokesSolver
3497 * constructor
for using LEVEL SET
3500 * NavierStokesSolver(
const unsigned int degree_LS,
3501 *
const unsigned int degree_U,
3502 *
const double time_step,
3504 *
const double rho_air,
3505 *
const double nu_air,
3506 *
const double rho_fluid,
3507 *
const double nu_fluid,
3509 *
const bool verbose,
3514 * constructor
for NOT LEVEL SET
3517 * NavierStokesSolver(
const unsigned int degree_LS,
3518 *
const unsigned int degree_U,
3519 *
const double time_step,
3523 *
const bool verbose,
3532 *
void set_rho_and_nu_functions(
const Function<dim> &rho_function,
3550 * boundary conditions
3553 *
void set_boundary_conditions(std::vector<types::global_dof_index> boundary_values_id_u,
3554 * std::vector<types::global_dof_index> boundary_values_id_v, std::vector<double> boundary_values_u,
3555 * std::vector<double> boundary_values_v);
3556 *
void set_boundary_conditions(std::vector<types::global_dof_index> boundary_values_id_u,
3557 * std::vector<types::global_dof_index> boundary_values_id_v,
3558 * std::vector<types::global_dof_index> boundary_values_id_w, std::vector<double> boundary_values_u,
3559 * std::vector<double> boundary_values_v, std::vector<double> boundary_values_w);
3577 *
void nth_time_step();
3585 * ~NavierStokesSolver();
3590 * SETUP AND INITIAL CONDITION
3594 *
void setup_VECTORS();
3595 *
void init_constraints();
3601 *
void assemble_system_U();
3602 *
void assemble_system_dpsi_q();
3609 * std::shared_ptr<PETScWrappers::PreconditionBoomerAMG> preconditioner,
3613 * std::shared_ptr<PETScWrappers::PreconditionBoomerAMG> preconditioner,
3618 * GET DIFFERENT FIELDS
3621 *
void get_rho_and_nu(
double phi);
3622 *
void get_velocity();
3623 *
void get_pressure();
3629 *
void save_old_solution();
3638 *
IndexSet locally_relevant_dofs_LS;
3644 *
IndexSet locally_relevant_dofs_U;
3649 *
IndexSet locally_relevant_dofs_P;
3664 *
unsigned int LEVEL_SET;
3665 *
unsigned int RHO_TIMES_RHS;
3681 * std::vector<types::global_dof_index> boundary_values_id_u;
3682 * std::vector<types::global_dof_index> boundary_values_id_v;
3683 * std::vector<types::global_dof_index> boundary_values_id_w;
3684 * std::vector<double> boundary_values_u;
3685 * std::vector<double> boundary_values_v;
3686 * std::vector<double> boundary_values_w;
3691 *
bool rebuild_Matrix_U;
3692 * std::shared_ptr<PETScWrappers::PreconditionBoomerAMG> preconditioner_Matrix_u;
3693 * std::shared_ptr<PETScWrappers::PreconditionBoomerAMG> preconditioner_Matrix_v;
3694 * std::shared_ptr<PETScWrappers::PreconditionBoomerAMG> preconditioner_Matrix_w;
3696 * std::shared_ptr<PETScWrappers::PreconditionBoomerAMG> preconditioner_S;
3698 * std::shared_ptr<PETScWrappers::PreconditionBoomerAMG> preconditioner_M;
3700 *
bool rebuild_Matrix_U_preconditioners;
3701 *
bool rebuild_S_M_preconditioners;
3729 * CONSTRUCTOR FOR LEVEL SET
3733 * NavierStokesSolver<dim>::NavierStokesSolver(
const unsigned int degree_LS,
3734 *
const unsigned int degree_U,
3735 *
const double time_step,
3737 *
const double rho_air,
3738 *
const double nu_air,
3739 *
const double rho_fluid,
3740 *
const double nu_fluid,
3742 *
const bool verbose,
3746 * mpi_communicator(mpi_communicator),
3747 * triangulation(triangulation),
3748 * degree_LS(degree_LS),
3749 * dof_handler_LS(triangulation),
3751 * degree_U(degree_U),
3752 * dof_handler_U(triangulation),
3754 * dof_handler_P(triangulation),
3756 * force_function(force_function),
3759 * This is dummy since rho and nu
functions won
't be used
3762 * rho_function(force_function),
3763 * nu_function(force_function),
3766 * rho_fluid(rho_fluid),
3767 * nu_fluid(nu_fluid),
3768 * time_step(time_step),
3773 * pcout(std::cout,(Utilities::MPI::this_mpi_process(mpi_communicator)==0)),
3774 * rebuild_Matrix_U(true),
3775 * rebuild_S_M(true),
3776 * rebuild_Matrix_U_preconditioners(true),
3777 * rebuild_S_M_preconditioners(true)
3782 * CONSTRUCTOR NOT FOR LEVEL SET
3786 * NavierStokesSolver<dim>::NavierStokesSolver(const unsigned int degree_LS,
3787 * const unsigned int degree_U,
3788 * const double time_step,
3789 * Function<dim> &force_function,
3790 * Function<dim> &rho_function,
3791 * Function<dim> &nu_function,
3792 * const bool verbose,
3793 * parallel::distributed::Triangulation<dim> &triangulation,
3794 * MPI_Comm &mpi_communicator) :
3795 * mpi_communicator(mpi_communicator),
3796 * triangulation(triangulation),
3797 * degree_LS(degree_LS),
3798 * dof_handler_LS(triangulation),
3800 * degree_U(degree_U),
3801 * dof_handler_U(triangulation),
3803 * dof_handler_P(triangulation),
3805 * force_function(force_function),
3806 * rho_function(rho_function),
3807 * nu_function(nu_function),
3808 * time_step(time_step),
3812 * pcout(std::cout,(Utilities::MPI::this_mpi_process(mpi_communicator)==0)),
3813 * rebuild_Matrix_U(true),
3814 * rebuild_S_M(true),
3815 * rebuild_Matrix_U_preconditioners(true),
3816 * rebuild_S_M_preconditioners(true)
3820 * NavierStokesSolver<dim>::~NavierStokesSolver()
3822 * dof_handler_LS.clear();
3823 * dof_handler_U.clear();
3824 * dof_handler_P.clear();
3829 * /////////////////////////////////////////////////////////
3830 * ////////////////// SETTERS AND GETTERS //////////////////
3831 * /////////////////////////////////////////////////////////
3835 * void NavierStokesSolver<dim>::set_rho_and_nu_functions(const Function<dim> &rho_function,
3836 * const Function<dim> &nu_function)
3838 * this->rho_function=rho_function;
3839 * this->nu_function=nu_function;
3843 * void NavierStokesSolver<dim>::initial_condition(PETScWrappers::MPI::Vector locally_relevant_solution_phi,
3844 * PETScWrappers::MPI::Vector locally_relevant_solution_u,
3845 * PETScWrappers::MPI::Vector locally_relevant_solution_v,
3846 * PETScWrappers::MPI::Vector locally_relevant_solution_p)
3848 * this->locally_relevant_solution_phi=locally_relevant_solution_phi;
3849 * this->locally_relevant_solution_u=locally_relevant_solution_u;
3850 * this->locally_relevant_solution_v=locally_relevant_solution_v;
3851 * this->locally_relevant_solution_p=locally_relevant_solution_p;
3854 * set old vectors to the initial condition (just for first time step)
3857 * save_old_solution();
3861 * void NavierStokesSolver<dim>::initial_condition(PETScWrappers::MPI::Vector locally_relevant_solution_phi,
3862 * PETScWrappers::MPI::Vector locally_relevant_solution_u,
3863 * PETScWrappers::MPI::Vector locally_relevant_solution_v,
3864 * PETScWrappers::MPI::Vector locally_relevant_solution_w,
3865 * PETScWrappers::MPI::Vector locally_relevant_solution_p)
3867 * this->locally_relevant_solution_phi=locally_relevant_solution_phi;
3868 * this->locally_relevant_solution_u=locally_relevant_solution_u;
3869 * this->locally_relevant_solution_v=locally_relevant_solution_v;
3870 * this->locally_relevant_solution_w=locally_relevant_solution_w;
3871 * this->locally_relevant_solution_p=locally_relevant_solution_p;
3874 * set old vectors to the initial condition (just for first time step)
3877 * save_old_solution();
3881 * void NavierStokesSolver<dim>::set_boundary_conditions(std::vector<types::global_dof_index> boundary_values_id_u,
3882 * std::vector<types::global_dof_index> boundary_values_id_v,
3883 * std::vector<double> boundary_values_u,
3884 * std::vector<double> boundary_values_v)
3886 * this->boundary_values_id_u=boundary_values_id_u;
3887 * this->boundary_values_id_v=boundary_values_id_v;
3888 * this->boundary_values_u=boundary_values_u;
3889 * this->boundary_values_v=boundary_values_v;
3893 * void NavierStokesSolver<dim>::set_boundary_conditions(std::vector<types::global_dof_index> boundary_values_id_u,
3894 * std::vector<types::global_dof_index> boundary_values_id_v,
3895 * std::vector<types::global_dof_index> boundary_values_id_w,
3896 * std::vector<double> boundary_values_u,
3897 * std::vector<double> boundary_values_v,
3898 * std::vector<double> boundary_values_w)
3900 * this->boundary_values_id_u=boundary_values_id_u;
3901 * this->boundary_values_id_v=boundary_values_id_v;
3902 * this->boundary_values_id_w=boundary_values_id_w;
3903 * this->boundary_values_u=boundary_values_u;
3904 * this->boundary_values_v=boundary_values_v;
3905 * this->boundary_values_w=boundary_values_w;
3909 * void NavierStokesSolver<dim>::set_velocity(PETScWrappers::MPI::Vector locally_relevant_solution_u,
3910 * PETScWrappers::MPI::Vector locally_relevant_solution_v)
3912 * this->locally_relevant_solution_u=locally_relevant_solution_u;
3913 * this->locally_relevant_solution_v=locally_relevant_solution_v;
3917 * void NavierStokesSolver<dim>::set_velocity(PETScWrappers::MPI::Vector locally_relevant_solution_u,
3918 * PETScWrappers::MPI::Vector locally_relevant_solution_v,
3919 * PETScWrappers::MPI::Vector locally_relevant_solution_w)
3921 * this->locally_relevant_solution_u=locally_relevant_solution_u;
3922 * this->locally_relevant_solution_v=locally_relevant_solution_v;
3923 * this->locally_relevant_solution_w=locally_relevant_solution_w;
3927 * void NavierStokesSolver<dim>::set_phi(PETScWrappers::MPI::Vector locally_relevant_solution_phi)
3929 * this->locally_relevant_solution_phi=locally_relevant_solution_phi;
3933 * void NavierStokesSolver<dim>::get_rho_and_nu(double phi)
3943 * else if (phi<-eps)
3947 * rho_value=rho_fluid*(1+H)/2.+rho_air*(1-H)/2.;
3948 * nu_value=nu_fluid*(1+H)/2.+nu_air*(1-H)/2.;
3951 * rho_value=rho_fluid*(1+phi)/2.+rho_air*(1-phi)/2.;
3952 * nu_value=nu_fluid*(1+phi)/2.+nu_air*(1-phi)/2.;
3958 * void NavierStokesSolver<dim>::get_pressure(PETScWrappers::MPI::Vector &locally_relevant_solution_p)
3960 * locally_relevant_solution_p=this->locally_relevant_solution_p;
3964 * void NavierStokesSolver<dim>::get_velocity(PETScWrappers::MPI::Vector &locally_relevant_solution_u,
3965 * PETScWrappers::MPI::Vector &locally_relevant_solution_v)
3967 * locally_relevant_solution_u=this->locally_relevant_solution_u;
3968 * locally_relevant_solution_v=this->locally_relevant_solution_v;
3972 * void NavierStokesSolver<dim>::get_velocity(PETScWrappers::MPI::Vector &locally_relevant_solution_u,
3973 * PETScWrappers::MPI::Vector &locally_relevant_solution_v,
3974 * PETScWrappers::MPI::Vector &locally_relevant_solution_w)
3976 * locally_relevant_solution_u=this->locally_relevant_solution_u;
3977 * locally_relevant_solution_v=this->locally_relevant_solution_v;
3978 * locally_relevant_solution_w=this->locally_relevant_solution_w;
3983 * ///////////////////////////////////////////////////
3984 * /////////// SETUP AND INITIAL CONDITION ///////////
3985 * ///////////////////////////////////////////////////
3989 * void NavierStokesSolver<dim>::setup()
3991 * pcout<<"***** SETUP IN NAVIER STOKES SOLVER *****"<<std::endl;
3993 * init_constraints();
3998 * void NavierStokesSolver<dim>::setup_DOF()
4001 * degree_MAX=std::max(degree_LS,degree_U);
4007 * dof_handler_LS.distribute_dofs(fe_LS);
4008 * locally_owned_dofs_LS = dof_handler_LS.locally_owned_dofs();
4009 * locally_relevant_dofs_LS = DoFTools::extract_locally_relevant_dofs(dof_handler_LS);
4015 * dof_handler_U.distribute_dofs(fe_U);
4016 * locally_owned_dofs_U = dof_handler_U.locally_owned_dofs();
4017 * locally_relevant_dofs_U = DoFTools::extract_locally_relevant_dofs(dof_handler_U);
4023 * dof_handler_P.distribute_dofs(fe_P);
4024 * locally_owned_dofs_P = dof_handler_P.locally_owned_dofs();
4025 * locally_relevant_dofs_P = DoFTools::extract_locally_relevant_dofs(dof_handler_P);
4029 * void NavierStokesSolver<dim>::setup_VECTORS()
4033 * init vectors for phi
4036 * locally_relevant_solution_phi.reinit(locally_owned_dofs_LS,locally_relevant_dofs_LS,
4037 * mpi_communicator);
4038 * locally_relevant_solution_phi=0;
4041 * init vectors for u
4044 * locally_relevant_solution_u.reinit(locally_owned_dofs_U,locally_relevant_dofs_U,
4045 * mpi_communicator);
4046 * locally_relevant_solution_u=0;
4047 * completely_distributed_solution_u.reinit(locally_owned_dofs_U,mpi_communicator);
4048 * system_rhs_u.reinit(locally_owned_dofs_U,mpi_communicator);
4051 * init vectors for u_old
4054 * locally_relevant_solution_u_old.reinit(locally_owned_dofs_U,locally_relevant_dofs_U,
4055 * mpi_communicator);
4056 * locally_relevant_solution_u_old=0;
4059 * init vectors for v
4062 * locally_relevant_solution_v.reinit(locally_owned_dofs_U,locally_relevant_dofs_U,
4063 * mpi_communicator);
4064 * locally_relevant_solution_v=0;
4065 * completely_distributed_solution_v.reinit(locally_owned_dofs_U,mpi_communicator);
4066 * system_rhs_v.reinit(locally_owned_dofs_U,mpi_communicator);
4069 * init vectors for v_old
4072 * locally_relevant_solution_v_old.reinit(locally_owned_dofs_U,locally_relevant_dofs_U,
4073 * mpi_communicator);
4074 * locally_relevant_solution_v_old=0;
4077 * init vectors for w
4080 * locally_relevant_solution_w.reinit(locally_owned_dofs_U,locally_relevant_dofs_U,
4081 * mpi_communicator);
4082 * locally_relevant_solution_w=0;
4083 * completely_distributed_solution_w.reinit(locally_owned_dofs_U,mpi_communicator);
4084 * system_rhs_w.reinit(locally_owned_dofs_U,mpi_communicator);
4087 * init vectors for w_old
4090 * locally_relevant_solution_w_old.reinit(locally_owned_dofs_U,locally_relevant_dofs_U,
4091 * mpi_communicator);
4092 * locally_relevant_solution_w_old=0;
4095 * init vectors for dpsi
4098 * locally_relevant_solution_psi.reinit(locally_owned_dofs_P,locally_relevant_dofs_P,
4099 * mpi_communicator);
4100 * locally_relevant_solution_psi=0;
4101 * system_rhs_psi.reinit(locally_owned_dofs_P,mpi_communicator);
4104 * init vectors for dpsi old
4107 * locally_relevant_solution_psi_old.reinit(locally_owned_dofs_P,locally_relevant_dofs_P,
4108 * mpi_communicator);
4109 * locally_relevant_solution_psi_old=0;
4112 * init vectors for q
4115 * completely_distributed_solution_q.reinit(locally_owned_dofs_P,mpi_communicator);
4116 * system_rhs_q.reinit(locally_owned_dofs_P,mpi_communicator);
4119 * init vectors for psi
4122 * completely_distributed_solution_psi.reinit(locally_owned_dofs_P,mpi_communicator);
4125 * init vectors for p
4128 * locally_relevant_solution_p.reinit(locally_owned_dofs_P,locally_relevant_dofs_P,
4129 * mpi_communicator);
4130 * locally_relevant_solution_p=0;
4131 * completely_distributed_solution_p.reinit(locally_owned_dofs_P,mpi_communicator);
4134 * ////////////////////////
4135 * Initialize constraints
4136 * ////////////////////////
4139 * init_constraints();
4142 * //////////////////
4144 * //////////////////
4145 * sparsity pattern for A
4148 * DynamicSparsityPattern dsp_Matrix(locally_relevant_dofs_U);
4149 * DoFTools::make_sparsity_pattern(dof_handler_U,dsp_Matrix,constraints,false);
4150 * SparsityTools::distribute_sparsity_pattern(dsp_Matrix,
4151 * dof_handler_U.locally_owned_dofs(),
4153 * locally_relevant_dofs_U);
4154 * system_Matrix_u.reinit(dof_handler_U.locally_owned_dofs(),
4155 * dof_handler_U.locally_owned_dofs(),
4157 * mpi_communicator);
4158 * system_Matrix_v.reinit(dof_handler_U.locally_owned_dofs(),
4159 * dof_handler_U.locally_owned_dofs(),
4161 * mpi_communicator);
4162 * system_Matrix_w.reinit(dof_handler_U.locally_owned_dofs(),
4163 * dof_handler_U.locally_owned_dofs(),
4165 * mpi_communicator);
4166 * rebuild_Matrix_U=true;
4169 * sparsity pattern for S
4172 * DynamicSparsityPattern dsp_S(locally_relevant_dofs_P);
4173 * DoFTools::make_sparsity_pattern(dof_handler_P,dsp_S,constraints_psi,false);
4174 * SparsityTools::distribute_sparsity_pattern(dsp_S,
4175 * dof_handler_P.locally_owned_dofs(),
4177 * locally_relevant_dofs_P);
4178 * system_S.reinit(dof_handler_P.locally_owned_dofs(),
4179 * dof_handler_P.locally_owned_dofs(),
4181 * mpi_communicator);
4184 * sparsity pattern for M
4187 * DynamicSparsityPattern dsp_M(locally_relevant_dofs_P);
4188 * DoFTools::make_sparsity_pattern(dof_handler_P,dsp_M,constraints_psi,false);
4189 * SparsityTools::distribute_sparsity_pattern(dsp_M,
4190 * dof_handler_P.locally_owned_dofs(),
4192 * locally_relevant_dofs_P);
4193 * system_M.reinit(dof_handler_P.locally_owned_dofs(),
4194 * dof_handler_P.locally_owned_dofs(),
4196 * mpi_communicator);
4201 * void NavierStokesSolver<dim>::init_constraints()
4208 * constraints.clear();
4209 * #if DEAL_II_VERSION_GTE(9, 6, 0)
4210 * constraints.reinit(locally_owned_dofs_U, locally_relevant_dofs_U);
4212 * constraints.reinit(locally_relevant_dofs_U);
4214 * DoFTools::make_hanging_node_constraints(dof_handler_U,constraints);
4215 * constraints.close();
4218 * constraints for dpsi
4221 * constraints_psi.clear();
4222 * #if DEAL_II_VERSION_GTE(9, 6, 0)
4223 * constraints_psi.reinit(locally_owned_dofs_P, locally_relevant_dofs_P);
4225 * constraints_psi.reinit(locally_relevant_dofs_P);
4227 * DoFTools::make_hanging_node_constraints(dof_handler_P,constraints_psi);
4230 * if (constraints_psi.can_store_line(0))
4231 * constraints_psi.add_line(0); //constraint u0 = 0
4234 * constraints_psi.close();
4239 * ///////////////////////////////////////////////////
4240 * //////////////// ASSEMBLE SYSTEMS /////////////////
4241 * ///////////////////////////////////////////////////
4245 * void NavierStokesSolver<dim>::assemble_system_U()
4247 * if (rebuild_Matrix_U==true)
4249 * system_Matrix_u=0;
4250 * system_Matrix_v=0;
4251 * system_Matrix_w=0;
4257 * const QGauss<dim> quadrature_formula(degree_MAX+1);
4258 * FEValues<dim> fe_values_LS(fe_LS,quadrature_formula,
4259 * update_values|update_gradients|update_quadrature_points|update_JxW_values);
4260 * FEValues<dim> fe_values_U(fe_U,quadrature_formula,
4261 * update_values|update_gradients|update_quadrature_points|update_JxW_values);
4262 * FEValues<dim> fe_values_P(fe_P,quadrature_formula,
4263 * update_values|update_gradients|update_quadrature_points|update_JxW_values);
4265 * const unsigned int dofs_per_cell=fe_U.dofs_per_cell;
4266 * const unsigned int n_q_points=quadrature_formula.size();
4268 * FullMatrix<double> cell_A_u(dofs_per_cell,dofs_per_cell);
4269 * Vector<double> cell_rhs_u(dofs_per_cell);
4270 * Vector<double> cell_rhs_v(dofs_per_cell);
4271 * Vector<double> cell_rhs_w(dofs_per_cell);
4273 * std::vector<double> phiqnp1(n_q_points);
4275 * std::vector<double> uqn(n_q_points);
4276 * std::vector<double> uqnm1(n_q_points);
4277 * std::vector<double> vqn(n_q_points);
4278 * std::vector<double> vqnm1(n_q_points);
4279 * std::vector<double> wqn(n_q_points);
4280 * std::vector<double> wqnm1(n_q_points);
4284 * FOR Explicit nonlinearity
4285 * std::vector<Tensor<1, dim> > grad_un(n_q_points);
4286 * std::vector<Tensor<1, dim> > grad_vn(n_q_points);
4287 * std::vector<Tensor<1, dim> > grad_wn(n_q_points);
4288 * Tensor<1, dim> Un;
4294 * std::vector<Tensor<1, dim> > grad_pqn(n_q_points);
4295 * std::vector<Tensor<1, dim> > grad_psiqn(n_q_points);
4296 * std::vector<Tensor<1, dim> > grad_psiqnm1(n_q_points);
4298 * std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
4299 * std::vector<Tensor<1, dim> > shape_grad(dofs_per_cell);
4300 * std::vector<double> shape_value(dofs_per_cell);
4305 * double pressure_grad_u;
4306 * double pressure_grad_v;
4307 * double pressure_grad_w;
4313 * Vector<double> force_terms(dim);
4315 * typename DoFHandler<dim>::active_cell_iterator
4316 * cell_U=dof_handler_U.begin_active(), endc_U=dof_handler_U.end();
4317 * typename DoFHandler<dim>::active_cell_iterator cell_P=dof_handler_P.begin_active();
4318 * typename DoFHandler<dim>::active_cell_iterator cell_LS=dof_handler_LS.begin_active();
4320 * for (; cell_U!=endc_U; ++cell_U,++cell_P,++cell_LS)
4321 * if (cell_U->is_locally_owned())
4328 * fe_values_LS.reinit(cell_LS);
4329 * fe_values_U.reinit(cell_U);
4330 * fe_values_P.reinit(cell_P);
4334 * get function values for LS
4337 * fe_values_LS.get_function_values(locally_relevant_solution_phi,phiqnp1);
4340 * get function values for U
4343 * fe_values_U.get_function_values(locally_relevant_solution_u,uqn);
4344 * fe_values_U.get_function_values(locally_relevant_solution_u_old,uqnm1);
4345 * fe_values_U.get_function_values(locally_relevant_solution_v,vqn);
4346 * fe_values_U.get_function_values(locally_relevant_solution_v_old,vqnm1);
4349 * fe_values_U.get_function_values(locally_relevant_solution_w,wqn);
4350 * fe_values_U.get_function_values(locally_relevant_solution_w_old,wqnm1);
4354 * For explicit nonlinearity
4355 * get gradient values for U
4356 * fe_values_U.get_function_gradients(locally_relevant_solution_u,grad_un);
4357 * fe_values_U.get_function_gradients(locally_relevant_solution_v,grad_vn);
4359 * fe_values_U.get_function_gradients(locally_relevant_solution_w,grad_wn);
4363 * get values and gradients for p and dpsi
4366 * fe_values_P.get_function_gradients(locally_relevant_solution_p,grad_pqn);
4367 * fe_values_P.get_function_gradients(locally_relevant_solution_psi,grad_psiqn);
4368 * fe_values_P.get_function_gradients(locally_relevant_solution_psi_old,grad_psiqnm1);
4370 * for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
4372 * const double JxW=fe_values_U.JxW(q_point);
4373 * for (unsigned int i=0; i<dofs_per_cell; ++i)
4375 * shape_grad[i]=fe_values_U.shape_grad(i,q_point);
4376 * shape_value[i]=fe_values_U.shape_value(i,q_point);
4379 * pressure_grad_u=(grad_pqn[q_point][0]+4./3*grad_psiqn[q_point][0]-1./3*grad_psiqnm1[q_point][0]);
4380 * pressure_grad_v=(grad_pqn[q_point][1]+4./3*grad_psiqn[q_point][1]-1./3*grad_psiqnm1[q_point][1]);
4382 * pressure_grad_w=(grad_pqn[q_point][2]+4./3*grad_psiqn[q_point][2]-1./3*grad_psiqnm1[q_point][2]);
4384 * if (LEVEL_SET==1) // use level set to define rho and nu
4385 * get_rho_and_nu(phiqnp1[q_point]);
4386 * else // rho and nu are defined through functions
4388 * rho_value=rho_function.value(fe_values_U.quadrature_point(q_point));
4389 * nu_value=nu_function.value(fe_values_U.quadrature_point(q_point));
4394 * Non-linearity: for semi-implicit
4397 * u_star=2*uqn[q_point]-uqnm1[q_point];
4398 * v_star=2*vqn[q_point]-vqnm1[q_point];
4400 * w_star=2*wqn[q_point]-wqnm1[q_point];
4404 * for explicit nonlinearity
4405 * Un[0] = uqn[q_point];
4406 * Un[1] = vqn[q_point];
4408 * Un[2] = wqn[q_point];
4412 * double nonlinearity_u = Un*grad_un[q_point];
4413 * double nonlinearity_v = Un*grad_vn[q_point];
4414 * double nonlinearity_w = 0;
4416 * nonlinearity_w = Un*grad_wn[q_point];
4422 * rho_star=rho_value; // This is because we consider rho*u_t instead of (rho*u)_t
4430 * force_function.vector_value(fe_values_U.quadrature_point(q_point),force_terms);
4431 * force_u=force_terms[0];
4432 * force_v=force_terms[1];
4434 * force_w=force_terms[2];
4435 * if (RHO_TIMES_RHS==1)
4443 * for (unsigned int i=0; i<dofs_per_cell; ++i)
4445 * cell_rhs_u(i)+=((4./3*rho*uqn[q_point]-1./3*rho*uqnm1[q_point]
4446 * +2./3*time_step*(force_u-pressure_grad_u)
4449 * -2./3*time_step*rho*nonlinearity_u
4452 * )*shape_value[i])*JxW;
4453 * cell_rhs_v(i)+=((4./3*rho*vqn[q_point]-1./3*rho*vqnm1[q_point]
4454 * +2./3*time_step*(force_v-pressure_grad_v)
4457 * -2./3*time_step*rho*nonlinearity_v
4460 * )*shape_value[i])*JxW;
4462 * cell_rhs_w(i)+=((4./3*rho*wqn[q_point]-1./3*rho*wqnm1[q_point]
4463 * +2./3*time_step*(force_w-pressure_grad_w)
4466 * -2./3*time_step*rho*nonlinearity_w
4469 * )*shape_value[i])*JxW;
4470 * if (rebuild_Matrix_U==true)
4471 * for (unsigned int j=0; j<dofs_per_cell; ++j)
4474 * cell_A_u(i,j)+=(rho_star*shape_value[i]*shape_value[j]
4475 * +2./3*time_step*nu_value*(shape_grad[i]*shape_grad[j])
4476 * +2./3*time_step*rho*shape_value[i]
4477 * *(u_star*shape_grad[j][0]+v_star*shape_grad[j][1]) // semi-implicit NL
4480 * cell_A_u(i,j)+=(rho_star*shape_value[i]*shape_value[j]
4481 * +2./3*time_step*nu_value*(shape_grad[i]*shape_grad[j])
4482 * +2./3*time_step*rho*shape_value[i]
4483 * *(u_star*shape_grad[j][0]+v_star*shape_grad[j][1]+w_star*shape_grad[j][2]) // semi-implicit NL
4488 * cell_U->get_dof_indices(local_dof_indices);
4494 * if (rebuild_Matrix_U==true)
4495 * constraints.distribute_local_to_global(cell_A_u,local_dof_indices,system_Matrix_u);
4496 * constraints.distribute_local_to_global(cell_rhs_u,local_dof_indices,system_rhs_u);
4497 * constraints.distribute_local_to_global(cell_rhs_v,local_dof_indices,system_rhs_v);
4499 * constraints.distribute_local_to_global(cell_rhs_w,local_dof_indices,system_rhs_w);
4501 * system_rhs_u.compress(VectorOperation::add);
4502 * system_rhs_v.compress(VectorOperation::add);
4503 * if (dim==3) system_rhs_w.compress(VectorOperation::add);
4504 * if (rebuild_Matrix_U==true)
4506 * system_Matrix_u.compress(VectorOperation::add);
4507 * system_Matrix_v.copy_from(system_Matrix_u);
4509 * system_Matrix_w.copy_from(system_Matrix_u);
4513 * BOUNDARY CONDITIONS
4516 * system_rhs_u.set(boundary_values_id_u,boundary_values_u);
4517 * system_rhs_u.compress(VectorOperation::insert);
4518 * system_rhs_v.set(boundary_values_id_v,boundary_values_v);
4519 * system_rhs_v.compress(VectorOperation::insert);
4522 * system_rhs_w.set(boundary_values_id_w,boundary_values_w);
4523 * system_rhs_w.compress(VectorOperation::insert);
4525 * if (rebuild_Matrix_U)
4527 * system_Matrix_u.clear_rows(boundary_values_id_u,1);
4528 * system_Matrix_v.clear_rows(boundary_values_id_v,1);
4530 * system_Matrix_w.clear_rows(boundary_values_id_w,1);
4531 * if (rebuild_Matrix_U_preconditioners)
4538 * rebuild_Matrix_U_preconditioners=false;
4539 * preconditioner_Matrix_u.reset(new PETScWrappers::PreconditionBoomerAMG
4540 * (system_Matrix_u,PETScWrappers::PreconditionBoomerAMG::AdditionalData(false)));
4541 * preconditioner_Matrix_v.reset( new PETScWrappers::PreconditionBoomerAMG
4542 * (system_Matrix_v,PETScWrappers::PreconditionBoomerAMG::AdditionalData(false)));
4544 * preconditioner_Matrix_w.reset(new PETScWrappers::PreconditionBoomerAMG
4545 * (system_Matrix_w,PETScWrappers::PreconditionBoomerAMG::AdditionalData(false)));
4548 * rebuild_Matrix_U=true;
4552 * void NavierStokesSolver<dim>::assemble_system_dpsi_q()
4554 * if (rebuild_S_M==true)
4562 * const QGauss<dim> quadrature_formula(degree_MAX+1);
4564 * FEValues<dim> fe_values_U(fe_U,quadrature_formula,
4565 * update_values|update_gradients|update_quadrature_points|update_JxW_values);
4566 * FEValues<dim> fe_values_P(fe_P,quadrature_formula,
4567 * update_values|update_gradients|update_quadrature_points|update_JxW_values);
4568 * FEValues<dim> fe_values_LS(fe_LS,quadrature_formula,
4569 * update_values|update_gradients|update_quadrature_points|update_JxW_values);
4571 * const unsigned int dofs_per_cell=fe_P.dofs_per_cell;
4572 * const unsigned int n_q_points=quadrature_formula.size();
4574 * FullMatrix<double> cell_S(dofs_per_cell,dofs_per_cell);
4575 * FullMatrix<double> cell_M(dofs_per_cell,dofs_per_cell);
4576 * Vector<double> cell_rhs_psi(dofs_per_cell);
4577 * Vector<double> cell_rhs_q(dofs_per_cell);
4579 * std::vector<double> phiqnp1(n_q_points);
4580 * std::vector<Tensor<1, dim> > gunp1(n_q_points);
4581 * std::vector<Tensor<1, dim> > gvnp1(n_q_points);
4582 * std::vector<Tensor<1, dim> > gwnp1(n_q_points);
4584 * std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
4585 * std::vector<double> shape_value(dofs_per_cell);
4586 * std::vector<Tensor<1, dim> > shape_grad(dofs_per_cell);
4588 * typename DoFHandler<dim>::active_cell_iterator
4589 * cell_P=dof_handler_P.begin_active(), endc_P=dof_handler_P.end();
4590 * typename DoFHandler<dim>::active_cell_iterator cell_U=dof_handler_U.begin_active();
4591 * typename DoFHandler<dim>::active_cell_iterator cell_LS=dof_handler_LS.begin_active();
4593 * for (; cell_P!=endc_P; ++cell_P,++cell_U,++cell_LS)
4594 * if (cell_P->is_locally_owned())
4601 * fe_values_P.reinit(cell_P);
4602 * fe_values_U.reinit(cell_U);
4603 * fe_values_LS.reinit(cell_LS);
4607 * get function values for LS
4610 * fe_values_LS.get_function_values(locally_relevant_solution_phi,phiqnp1);
4614 * get function grads for u and v
4617 * fe_values_U.get_function_gradients(locally_relevant_solution_u,gunp1);
4618 * fe_values_U.get_function_gradients(locally_relevant_solution_v,gvnp1);
4620 * fe_values_U.get_function_gradients(locally_relevant_solution_w,gwnp1);
4622 * for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
4624 * const double JxW=fe_values_P.JxW(q_point);
4625 * double divU = gunp1[q_point][0]+gvnp1[q_point][1];
4626 * if (dim==3) divU += gwnp1[q_point][2];
4627 * for (unsigned int i=0; i<dofs_per_cell; ++i)
4629 * shape_value[i]=fe_values_P.shape_value(i,q_point);
4630 * shape_grad[i]=fe_values_P.shape_grad(i,q_point);
4632 * if (LEVEL_SET==1) // use level set to define rho and nu
4633 * get_rho_and_nu (phiqnp1[q_point]);
4634 * else // rho and nu are defined through functions
4635 * nu_value=nu_function.value(fe_values_U.quadrature_point(q_point));
4637 * for (unsigned int i=0; i<dofs_per_cell; ++i)
4639 * cell_rhs_psi(i)+=-3./2./time_step*rho_min*divU*shape_value[i]*JxW;
4640 * cell_rhs_q(i)-=nu_value*divU*shape_value[i]*JxW;
4641 * if (rebuild_S_M==true)
4643 * for (unsigned int j=0; j<dofs_per_cell; ++j)
4646 * cell_S(i,j)+=shape_grad[i]*shape_grad[j]*JxW+1E-10;
4647 * cell_M(i,j)+=shape_value[i]*shape_value[j]*JxW;
4651 * cell_S(i,j)+=shape_grad[i]*shape_grad[j]*JxW;
4652 * cell_M(i,j)+=shape_value[i]*shape_value[j]*JxW;
4657 * cell_P->get_dof_indices(local_dof_indices);
4663 * if (rebuild_S_M==true)
4665 * constraints_psi.distribute_local_to_global(cell_S,local_dof_indices,system_S);
4666 * constraints_psi.distribute_local_to_global(cell_M,local_dof_indices,system_M);
4668 * constraints_psi.distribute_local_to_global(cell_rhs_q,local_dof_indices,system_rhs_q);
4669 * constraints_psi.distribute_local_to_global(cell_rhs_psi,local_dof_indices,system_rhs_psi);
4671 * if (rebuild_S_M==true)
4673 * system_M.compress(VectorOperation::add);
4674 * system_S.compress(VectorOperation::add);
4675 * if (rebuild_S_M_preconditioners)
4677 * rebuild_S_M_preconditioners=false;
4678 * preconditioner_S.reset(new PETScWrappers::PreconditionBoomerAMG
4679 * (system_S,PETScWrappers::PreconditionBoomerAMG::AdditionalData(true)));
4680 * preconditioner_M.reset(new PETScWrappers::PreconditionBoomerAMG
4681 * (system_M,PETScWrappers::PreconditionBoomerAMG::AdditionalData(true)));
4684 * system_rhs_psi.compress(VectorOperation::add);
4685 * system_rhs_q.compress(VectorOperation::add);
4686 * rebuild_S_M=false;
4691 * ///////////////////////////////////////////////////
4692 * ///////////////////// SOLVERS /////////////////////
4693 * ///////////////////////////////////////////////////
4697 * void NavierStokesSolver<dim>::solve_U(const AffineConstraints<double> &constraints,
4698 * PETScWrappers::MPI::SparseMatrix &Matrix,
4699 * std::shared_ptr<PETScWrappers::PreconditionBoomerAMG> preconditioner,
4700 * PETScWrappers::MPI::Vector &completely_distributed_solution,
4701 * const PETScWrappers::MPI::Vector &rhs)
4703 * SolverControl solver_control(dof_handler_U.n_dofs(),1e-6);
4706 * PETScWrappers::SolverCG solver(solver_control);
4707 * PETScWrappers::SolverGMRES solver(solver_control);
4708 * PETScWrappers::SolverChebychev solver(solver_control);
4711 * PETScWrappers::SolverBicgstab solver(solver_control);
4712 * constraints.distribute(completely_distributed_solution);
4713 * solver.solve(Matrix,completely_distributed_solution,rhs,*preconditioner);
4714 * constraints.distribute(completely_distributed_solution);
4715 * if (solver_control.last_step() > MAX_NUM_ITER_TO_RECOMPUTE_PRECONDITIONER)
4716 * rebuild_Matrix_U_preconditioners=true;
4717 * if (verbose==true)
4718 * pcout<<" Solved U in "<<solver_control.last_step()<<" iterations."<<std::endl;
4722 * void NavierStokesSolver<dim>::solve_P(const AffineConstraints<double> &constraints,
4723 * PETScWrappers::MPI::SparseMatrix &Matrix,
4724 * std::shared_ptr<PETScWrappers::PreconditionBoomerAMG> preconditioner,
4725 * PETScWrappers::MPI::Vector &completely_distributed_solution,
4726 * const PETScWrappers::MPI::Vector &rhs)
4728 * SolverControl solver_control(dof_handler_P.n_dofs(),1e-6);
4729 * PETScWrappers::SolverCG solver(solver_control);
4732 * PETScWrappers::SolverGMRES solver(solver_control);
4735 * constraints.distribute(completely_distributed_solution);
4736 * solver.solve(Matrix,completely_distributed_solution,rhs,*preconditioner);
4737 * constraints.distribute(completely_distributed_solution);
4738 * if (solver_control.last_step() > MAX_NUM_ITER_TO_RECOMPUTE_PRECONDITIONER)
4739 * rebuild_S_M_preconditioners=true;
4740 * if (verbose==true)
4741 * pcout<<" Solved P in "<<solver_control.last_step()<<" iterations."<<std::endl;
4746 * ///////////////////////////////////////////////////
4747 * ////////////// get different fields ///////////////
4748 * ///////////////////////////////////////////////////
4752 * void NavierStokesSolver<dim>::get_velocity()
4754 * assemble_system_U();
4755 * save_old_solution();
4756 * solve_U(constraints,system_Matrix_u,preconditioner_Matrix_u,completely_distributed_solution_u,system_rhs_u);
4757 * locally_relevant_solution_u=completely_distributed_solution_u;
4758 * solve_U(constraints,system_Matrix_v,preconditioner_Matrix_v,completely_distributed_solution_v,system_rhs_v);
4759 * locally_relevant_solution_v=completely_distributed_solution_v;
4762 * solve_U(constraints,system_Matrix_w,preconditioner_Matrix_w,completely_distributed_solution_w,system_rhs_w);
4763 * locally_relevant_solution_w=completely_distributed_solution_w;
4768 * void NavierStokesSolver<dim>::get_pressure()
4775 * assemble_system_dpsi_q();
4776 * solve_P(constraints_psi,system_S,preconditioner_S,completely_distributed_solution_psi,system_rhs_psi);
4777 * locally_relevant_solution_psi=completely_distributed_solution_psi;
4783 * solve_P(constraints,system_M,preconditioner_M,completely_distributed_solution_q,system_rhs_q);
4786 * UPDATE THE PRESSURE
4789 * completely_distributed_solution_p.add(1,completely_distributed_solution_psi);
4790 * completely_distributed_solution_p.add(1,completely_distributed_solution_q);
4791 * locally_relevant_solution_p = completely_distributed_solution_p;
4796 * ///////////////////////////////////////////////////
4797 * ///////////////////// DO STEPS ////////////////////
4798 * ///////////////////////////////////////////////////
4802 * void NavierStokesSolver<dim>::nth_time_step()
4810 * ///////////////////////////////////////////////////
4811 * ////////////////////// OTHERS /////////////////////
4812 * ///////////////////////////////////////////////////
4816 * void NavierStokesSolver<dim>::save_old_solution()
4818 * locally_relevant_solution_u_old=locally_relevant_solution_u;
4819 * locally_relevant_solution_v_old=locally_relevant_solution_v;
4820 * locally_relevant_solution_w_old=locally_relevant_solution_w;
4821 * locally_relevant_solution_psi_old=locally_relevant_solution_psi;
4827<a name="ann-TestLevelSet.cc"></a>
4828<h1>Annotated version of TestLevelSet.cc</h1>
4834 * /* -----------------------------------------------------------------------------
4836 * * SPDX-License-Identifier: LGPL-2.1-or-later
4837 * * Copyright (C) 2016 Manuel Quezada de Luna
4839 * * This file is part of the deal.II code gallery.
4841 * * -----------------------------------------------------------------------------
4844 * #include <deal.II/base/quadrature_lib.h>
4845 * #include <deal.II/base/function.h>
4846 * #include <deal.II/lac/affine_constraints.h>
4847 * #include <deal.II/lac/vector.h>
4848 * #include <deal.II/lac/full_matrix.h>
4849 * #include <deal.II/lac/solver_cg.h>
4850 * #include <deal.II/lac/petsc_sparse_matrix.h>
4851 * #include <deal.II/lac/petsc_vector.h>
4852 * #include <deal.II/lac/petsc_solver.h>
4853 * #include <deal.II/lac/petsc_precondition.h>
4854 * #include <deal.II/grid/grid_generator.h>
4855 * #include <deal.II/grid/tria_accessor.h>
4856 * #include <deal.II/grid/tria_iterator.h>
4857 * #include <deal.II/dofs/dof_handler.h>
4858 * #include <deal.II/dofs/dof_accessor.h>
4859 * #include <deal.II/dofs/dof_tools.h>
4860 * #include <deal.II/fe/fe_values.h>
4861 * #include <deal.II/fe/fe_q.h>
4862 * #include <deal.II/numerics/vector_tools.h>
4863 * #include <deal.II/numerics/data_out.h>
4864 * #include <deal.II/numerics/error_estimator.h>
4865 * #include <deal.II/base/utilities.h>
4866 * #include <deal.II/base/conditional_ostream.h>
4867 * #include <deal.II/base/index_set.h>
4868 * #include <deal.II/lac/sparsity_tools.h>
4869 * #include <deal.II/distributed/tria.h>
4870 * #include <deal.II/distributed/grid_refinement.h>
4871 * #include <deal.II/lac/petsc_vector.h>
4872 * #include <deal.II/base/convergence_table.h>
4873 * #include <deal.II/base/timer.h>
4874 * #include <deal.II/base/parameter_handler.h>
4875 * #include <deal.II/grid/grid_tools.h>
4876 * #include <deal.II/fe/mapping_q.h>
4877 * #include <deal.II/fe/fe_system.h>
4879 * #include <fstream>
4880 * #include <iostream>
4883 * using namespace dealii;
4887 * ///////////////////////
4888 * FOR TRANSPORT PROBLEM
4889 * ///////////////////////
4893 * #define FORWARD_EULER 0
4900 * #define CIRCULAR_ROTATION 0
4901 * #define DIAGONAL_ADVECTION 1
4907 * #define VARIABLE_VELOCITY 0
4909 * #include "utilities_test_LS.cc"
4910 * #include "LevelSetSolver.cc"
4914 * ///////////////////////////////////////////////////
4915 * /////////////////// MAIN CLASS ////////////////////
4916 * ///////////////////////////////////////////////////
4919 * template <int dim>
4920 * class TestLevelSet
4923 * TestLevelSet (const unsigned int degree_LS,
4924 * const unsigned int degree_U);
4934 * void set_boundary_inlet();
4935 * void get_boundary_values_phi(std::vector<unsigned int> &boundary_values_id_phi,
4936 * std::vector<double> &boundary_values_phi);
4942 * void get_interpolated_velocity();
4945 * SETUP AND INIT CONDITIONS
4949 * void initial_condition();
4950 * void init_constraints();
4956 * void process_solution(parallel::distributed::Triangulation<dim> &triangulation,
4957 * DoFHandler<dim> &dof_handler_LS,
4958 * PETScWrappers::MPI::Vector &solution);
4959 * void output_results();
4960 * void output_solution();
4967 * PETScWrappers::MPI::Vector locally_relevant_solution_phi;
4968 * PETScWrappers::MPI::Vector locally_relevant_solution_u;
4969 * PETScWrappers::MPI::Vector locally_relevant_solution_v;
4970 * PETScWrappers::MPI::Vector locally_relevant_solution_w;
4971 * PETScWrappers::MPI::Vector completely_distributed_solution_phi;
4972 * PETScWrappers::MPI::Vector completely_distributed_solution_u;
4973 * PETScWrappers::MPI::Vector completely_distributed_solution_v;
4974 * PETScWrappers::MPI::Vector completely_distributed_solution_w;
4980 * std::vector<unsigned int> boundary_values_id_phi;
4981 * std::vector<double> boundary_values_phi;
4988 * MPI_Comm mpi_communicator;
4989 * parallel::distributed::Triangulation<dim> triangulation;
4993 * DoFHandler<dim> dof_handler_LS;
4995 * IndexSet locally_owned_dofs_LS;
4996 * IndexSet locally_relevant_dofs_LS;
4999 * DoFHandler<dim> dof_handler_U;
5001 * IndexSet locally_owned_dofs_U;
5002 * IndexSet locally_relevant_dofs_U;
5004 * DoFHandler<dim> dof_handler_U_disp_field;
5005 * FESystem<dim> fe_U_disp_field;
5006 * IndexSet locally_owned_dofs_U_disp_field;
5007 * IndexSet locally_relevant_dofs_U_disp_field;
5009 * AffineConstraints<double> constraints;
5010 * AffineConstraints<double> constraints_disp_field;
5014 * double final_time;
5015 * unsigned int timestep_number;
5020 * int sharpness_integer;
5022 * unsigned int n_refinement;
5023 * unsigned int output_number;
5024 * double output_time;
5028 * ConditionalOStream pcout;
5035 * double cK; //compression coeff
5036 * double cE; //entropy-visc coeff
5037 * unsigned int TRANSPORT_TIME_INTEGRATION;
5038 * std::string ALGORITHM;
5039 * unsigned int PROBLEM;
5043 * FOR RECONSTRUCTION OF MATERIAL FIELDS
5046 * double eps, rho_air, rho_fluid;
5053 * PETScWrappers::MPI::SparseMatrix matrix_MC, matrix_MC_tnm1;
5054 * std::shared_ptr<PETScWrappers::PreconditionBoomerAMG> preconditioner_MC;
5058 * template <int dim>
5059 * TestLevelSet<dim>::TestLevelSet (const unsigned int degree_LS,
5060 * const unsigned int degree_U)
5062 * mpi_communicator (MPI_COMM_WORLD),
5063 * triangulation (mpi_communicator,
5064 * typename Triangulation<dim>::MeshSmoothing
5065 * (Triangulation<dim>::smoothing_on_refinement |
5066 * Triangulation<dim>::smoothing_on_coarsening)),
5067 * degree_LS(degree_LS),
5068 * dof_handler_LS (triangulation),
5069 * fe_LS (degree_LS),
5070 * degree_U(degree_U),
5071 * dof_handler_U (triangulation),
5073 * dof_handler_U_disp_field(triangulation),
5074 * fe_U_disp_field(FE_Q<dim>(degree_U),dim),
5075 * pcout (std::cout,(Utilities::MPI::this_mpi_process(mpi_communicator)== 0))
5078 * template <int dim>
5079 * TestLevelSet<dim>::~TestLevelSet ()
5081 * dof_handler_U_disp_field.clear();
5082 * dof_handler_LS.clear ();
5083 * dof_handler_U.clear ();
5092 * template <int dim>
5093 * void TestLevelSet<dim>::get_interpolated_velocity()
5100 * completely_distributed_solution_u = 0;
5101 * VectorTools::interpolate(dof_handler_U,
5102 * ExactU<dim>(PROBLEM,time),
5103 * completely_distributed_solution_u);
5104 * constraints.distribute (completely_distributed_solution_u);
5105 * locally_relevant_solution_u = completely_distributed_solution_u;
5111 * completely_distributed_solution_v = 0;
5112 * VectorTools::interpolate(dof_handler_U,
5113 * ExactV<dim>(PROBLEM,time),
5114 * completely_distributed_solution_v);
5115 * constraints.distribute (completely_distributed_solution_v);
5116 * locally_relevant_solution_v = completely_distributed_solution_v;
5119 * completely_distributed_solution_w = 0;
5120 * VectorTools::interpolate(dof_handler_U,
5121 * ExactW<dim>(PROBLEM,time),
5122 * completely_distributed_solution_w);
5123 * constraints.distribute (completely_distributed_solution_w);
5124 * locally_relevant_solution_w = completely_distributed_solution_w;
5135 * template <int dim>
5136 * void TestLevelSet<dim>::set_boundary_inlet()
5138 * const QGauss<dim-1> face_quadrature_formula(1); // center of the face
5139 * FEFaceValues<dim> fe_face_values (fe_U,face_quadrature_formula,
5140 * update_values | update_quadrature_points |
5141 * update_normal_vectors);
5142 * const unsigned int n_face_q_points = face_quadrature_formula.size();
5143 * std::vector<double> u_value (n_face_q_points);
5144 * std::vector<double> v_value (n_face_q_points);
5145 * std::vector<double> w_value (n_face_q_points);
5147 * typename DoFHandler<dim>::active_cell_iterator
5148 * cell_U = dof_handler_U.begin_active(),
5149 * endc_U = dof_handler_U.end();
5152 * for (; cell_U!=endc_U; ++cell_U)
5153 * if (cell_U->is_locally_owned())
5154 * for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
5155 * if (cell_U->face(face)->at_boundary())
5157 * fe_face_values.reinit(cell_U,face);
5158 * fe_face_values.get_function_values(locally_relevant_solution_u,u_value);
5159 * fe_face_values.get_function_values(locally_relevant_solution_v,v_value);
5161 * fe_face_values.get_function_values(locally_relevant_solution_w,w_value);
5166 * if (fe_face_values.normal_vector(0)*u < -1e-14)
5167 * cell_U->face(face)->set_boundary_id(10);
5171 * template <int dim>
5172 * void TestLevelSet<dim>::get_boundary_values_phi(std::vector<unsigned int> &boundary_values_id_phi,
5173 * std::vector<double> &boundary_values_phi)
5175 * std::map<unsigned int, double> map_boundary_values_phi;
5176 * unsigned int boundary_id=0;
5178 * set_boundary_inlet();
5179 * boundary_id=10; // inlet
5180 * VectorTools::interpolate_boundary_values (dof_handler_LS,
5181 * boundary_id,BoundaryPhi<dim>(),
5182 * map_boundary_values_phi);
5184 * boundary_values_id_phi.resize(map_boundary_values_phi.size());
5185 * boundary_values_phi.resize(map_boundary_values_phi.size());
5186 * std::map<unsigned int,double>::const_iterator boundary_value_phi = map_boundary_values_phi.begin();
5187 * for (int i=0; boundary_value_phi !=map_boundary_values_phi.end(); ++boundary_value_phi, ++i)
5189 * boundary_values_id_phi[i]=boundary_value_phi->first;
5190 * boundary_values_phi[i]=boundary_value_phi->second;
5196 * ///////////////////////////////
5197 * SETUP AND INITIAL CONDITIONS
5198 * //////////////////////////////
5201 * template <int dim>
5202 * void TestLevelSet<dim>::setup()
5204 * degree = std::max(degree_LS,degree_U);
5210 * dof_handler_LS.distribute_dofs (fe_LS);
5211 * locally_owned_dofs_LS = dof_handler_LS.locally_owned_dofs ();
5212 * locally_relevant_dofs_LS = DoFTools::extract_locally_relevant_dofs (dof_handler_LS);
5218 * dof_handler_U.distribute_dofs (fe_U);
5219 * locally_owned_dofs_U = dof_handler_U.locally_owned_dofs ();
5220 * locally_relevant_dofs_U = DoFTools::extract_locally_relevant_dofs (dof_handler_U);
5223 * setup system U for disp field
5226 * dof_handler_U_disp_field.distribute_dofs (fe_U_disp_field);
5227 * locally_owned_dofs_U_disp_field = dof_handler_U_disp_field.locally_owned_dofs ();
5228 * locally_relevant_dofs_U_disp_field = DoFTools::extract_locally_relevant_dofs (dof_handler_U_disp_field);
5231 * init vectors for phi
5234 * locally_relevant_solution_phi.reinit(locally_owned_dofs_LS,
5235 * locally_relevant_dofs_LS,
5236 * mpi_communicator);
5237 * locally_relevant_solution_phi = 0;
5238 * completely_distributed_solution_phi.reinit(mpi_communicator,
5239 * dof_handler_LS.n_dofs(),
5240 * dof_handler_LS.n_locally_owned_dofs());
5243 * init vectors for u
5246 * locally_relevant_solution_u.reinit(locally_owned_dofs_U,
5247 * locally_relevant_dofs_U,
5248 * mpi_communicator);
5249 * locally_relevant_solution_u = 0;
5250 * completely_distributed_solution_u.reinit(mpi_communicator,
5251 * dof_handler_U.n_dofs(),
5252 * dof_handler_U.n_locally_owned_dofs());
5255 * init vectors for v
5258 * locally_relevant_solution_v.reinit(locally_owned_dofs_U,
5259 * locally_relevant_dofs_U,
5260 * mpi_communicator);
5261 * locally_relevant_solution_v = 0;
5262 * completely_distributed_solution_v.reinit(mpi_communicator,
5263 * dof_handler_U.n_dofs(),
5264 * dof_handler_U.n_locally_owned_dofs());
5267 * init vectors for w
5270 * locally_relevant_solution_w.reinit(locally_owned_dofs_U,
5271 * locally_relevant_dofs_U,
5272 * mpi_communicator);
5273 * locally_relevant_solution_w = 0;
5274 * completely_distributed_solution_w.reinit(mpi_communicator,
5275 * dof_handler_U.n_dofs(),
5276 * dof_handler_U.n_locally_owned_dofs());
5277 * init_constraints();
5283 * DynamicSparsityPattern dsp (locally_relevant_dofs_LS);
5284 * DoFTools::make_sparsity_pattern (dof_handler_LS,dsp,constraints,false);
5286 * const std::vector<types::global_dof_index> n_locally_owned_dofs_per_processor =
5287 * Utilities::MPI::all_gather(mpi_communicator, dof_handler_LS.n_locally_owned_dofs());
5289 * SparsityTools::distribute_sparsity_pattern (dsp,
5290 * n_locally_owned_dofs_per_processor,
5292 * locally_relevant_dofs_LS);
5293 * matrix_MC.reinit (mpi_communicator,
5295 * n_locally_owned_dofs_per_processor,
5296 * n_locally_owned_dofs_per_processor,
5297 * Utilities::MPI::this_mpi_process(mpi_communicator));
5298 * matrix_MC_tnm1.reinit (mpi_communicator,
5300 * n_locally_owned_dofs_per_processor,
5301 * n_locally_owned_dofs_per_processor,
5302 * Utilities::MPI::this_mpi_process(mpi_communicator));
5305 * template <int dim>
5306 * void TestLevelSet<dim>::initial_condition()
5311 * Initial conditions
5312 * init condition for phi
5315 * completely_distributed_solution_phi = 0;
5316 * VectorTools::interpolate(dof_handler_LS,
5317 * InitialPhi<dim>(PROBLEM, sharpness),
5320 * Functions::ZeroFunction<dim>(),
5323 * completely_distributed_solution_phi);
5324 * constraints.distribute (completely_distributed_solution_phi);
5325 * locally_relevant_solution_phi = completely_distributed_solution_phi;
5328 * init condition for u=0
5331 * completely_distributed_solution_u = 0;
5332 * VectorTools::interpolate(dof_handler_U,
5333 * ExactU<dim>(PROBLEM,time),
5334 * completely_distributed_solution_u);
5335 * constraints.distribute (completely_distributed_solution_u);
5336 * locally_relevant_solution_u = completely_distributed_solution_u;
5339 * init condition for v
5342 * completely_distributed_solution_v = 0;
5343 * VectorTools::interpolate(dof_handler_U,
5344 * ExactV<dim>(PROBLEM,time),
5345 * completely_distributed_solution_v);
5346 * constraints.distribute (completely_distributed_solution_v);
5347 * locally_relevant_solution_v = completely_distributed_solution_v;
5350 * template <int dim>
5351 * void TestLevelSet<dim>::init_constraints()
5353 * constraints.clear ();
5354 * #if DEAL_II_VERSION_GTE(9, 6, 0)
5355 * constraints.reinit (locally_owned_dofs_LS, locally_relevant_dofs_LS);
5357 * constraints.reinit (locally_relevant_dofs_LS);
5359 * DoFTools::make_hanging_node_constraints (dof_handler_LS, constraints);
5360 * constraints.close ();
5361 * constraints_disp_field.clear ();
5362 * #if DEAL_II_VERSION_GTE(9, 6, 0)
5363 * constraints_disp_field.reinit (locally_owned_dofs_LS, locally_relevant_dofs_LS);
5365 * constraints_disp_field.reinit (locally_relevant_dofs_LS);
5367 * DoFTools::make_hanging_node_constraints (dof_handler_LS, constraints_disp_field);
5368 * constraints_disp_field.close ();
5378 * template <int dim>
5379 * void TestLevelSet<dim>::process_solution(parallel::distributed::Triangulation<dim> &triangulation,
5380 * DoFHandler<dim> &dof_handler_LS,
5381 * PETScWrappers::MPI::Vector &solution)
5383 * Vector<double> difference_per_cell (triangulation.n_active_cells());
5389 * VectorTools::integrate_difference (dof_handler_LS,
5391 * InitialPhi<dim>(PROBLEM,sharpness),
5392 * difference_per_cell,
5393 * QGauss<dim>(degree_LS+3),
5394 * VectorTools::L1_norm);
5396 * double u_L1_error = difference_per_cell.l1_norm();
5397 * u_L1_error = std::sqrt(Utilities::MPI::sum(u_L1_error * u_L1_error, mpi_communicator));
5399 * VectorTools::integrate_difference (dof_handler_LS,
5401 * InitialPhi<dim>(PROBLEM,sharpness),
5402 * difference_per_cell,
5403 * QGauss<dim>(degree_LS+3),
5404 * VectorTools::L2_norm);
5405 * double u_L2_error = difference_per_cell.l2_norm();
5406 * u_L2_error = std::sqrt(Utilities::MPI::sum(u_L2_error * u_L2_error, mpi_communicator));
5408 * pcout << "L1 error: " << u_L1_error << std::endl;
5409 * pcout << "L2 error: " << u_L2_error << std::endl;
5413 * void TestLevelSet<dim>::output_results()
5415 * output_solution();
5419 * template <int dim>
5420 * void TestLevelSet<dim>::output_solution()
5422 * DataOut<dim> data_out;
5423 * data_out.attach_dof_handler(dof_handler_LS);
5424 * data_out.add_data_vector (locally_relevant_solution_phi, "phi");
5425 * data_out.build_patches();
5427 * const std::string filename = ("solution-" +
5428 * Utilities::int_to_string (output_number, 3) +
5430 * Utilities::int_to_string
5431 * (triangulation.locally_owned_subdomain(), 4));
5432 * std::ofstream output ((filename + ".vtu").c_str());
5433 * data_out.write_vtu (output);
5435 * if (Utilities::MPI::this_mpi_process(mpi_communicator) == 0)
5437 * std::vector<std::string> filenames;
5438 * for (unsigned int i=0;
5439 * i<Utilities::MPI::n_mpi_processes(mpi_communicator);
5441 * filenames.push_back ("solution-" +
5442 * Utilities::int_to_string (output_number, 3) +
5444 * Utilities::int_to_string (i, 4) +
5447 * std::ofstream master_output ((filename + ".pvtu").c_str());
5448 * data_out.write_pvtu_record (master_output, filenames);
5452 * template <int dim>
5453 * void TestLevelSet<dim>::run()
5457 * ////////////////////
5458 * GENERAL PARAMETERS
5459 * ////////////////////
5464 * get_output = true;
5465 * output_number = 0;
5468 * output_time = 0.1;
5470 * PROBLEM=CIRCULAR_ROTATION;
5473 * PROBLEM=DIAGONAL_ADVECTION;
5477 * if (PROBLEM==CIRCULAR_ROTATION)
5478 * umax = std::sqrt(2)*numbers::PI;
5480 * umax = std::sqrt(2);
5484 * //////////////////////////////////
5485 * PARAMETERS FOR TRANSPORT PROBLEM
5486 * //////////////////////////////////
5489 * cK = 1.0; // compression constant
5490 * cE = 1.0; // entropy viscosity constant
5491 * sharpness_integer=1; //this will be multiplied by min_h
5494 * TRANSPORT_TIME_INTEGRATION=FORWARD_EULER;
5497 * TRANSPORT_TIME_INTEGRATION=SSP33;
5500 * ALGORITHM = "MPP_u1";
5503 * ALGORITHM = "NMPP_uH";
5506 * ALGORITHM = "MPP_uH";
5515 * if (PROBLEM==CIRCULAR_ROTATION || PROBLEM==DIAGONAL_ADVECTION)
5516 * GridGenerator::hyper_cube(triangulation);
5519 * GridGenerator::hyper_rectangle(triangulation, Point<dim>(0.0,0.0), Point<dim>(1.0,1.0), true);
5522 * triangulation.refine_global (n_refinement);
5535 * for Reconstruction of MATERIAL FIELDS
5538 * min_h = GridTools::minimal_cell_diameter(triangulation)/std::sqrt(dim)/degree;
5539 * eps=1*min_h; //For reconstruction of density in Navier Stokes
5540 * sharpness=sharpness_integer*min_h; //adjust value of sharpness (for init cond of phi)
5549 * time_step = cfl*min_h/umax;
5553 * //////////////////
5555 * //////////////////
5558 * LevelSetSolver<dim> level_set (degree_LS,degree_U,
5562 * TRANSPORT_TIME_INTEGRATION,
5564 * mpi_communicator);
5568 * ///////////////////
5570 * ///////////////////
5573 * initial_condition();
5576 * level_set.initial_condition(locally_relevant_solution_phi,
5577 * locally_relevant_solution_u,locally_relevant_solution_v);
5579 * level_set.initial_condition(locally_relevant_solution_phi,
5580 * locally_relevant_solution_u,locally_relevant_solution_v,locally_relevant_solution_w);
5584 * /////////////////////////////
5585 * BOUNDARY CONDITIONS FOR PHI
5586 * /////////////////////////////
5589 * get_boundary_values_phi(boundary_values_id_phi,boundary_values_phi);
5590 * level_set.set_boundary_conditions(boundary_values_id_phi,boundary_values_phi);
5594 * OUTPUT DATA REGARDING TIME STEPPING AND MESH
5597 * int dofs_LS = dof_handler_LS.n_dofs();
5598 * pcout << "Cfl: " << cfl << std::endl;
5599 * pcout << " Number of active cells: "
5600 * << triangulation.n_global_active_cells() << std::endl
5601 * << " Number of degrees of freedom: " << std::endl
5602 * << " LS: " << dofs_LS << std::endl;
5609 * timestep_number=0;
5611 * while (time<final_time)
5613 * timestep_number++;
5614 * if (time+time_step > final_time)
5616 * pcout << "FINAL TIME STEP... " << std::endl;
5617 * time_step = final_time-time;
5619 * pcout << "Time step " << timestep_number
5620 * << "\twith dt=" << time_step
5621 * << "\tat tn=" << time << std::endl;
5626 * GET VELOCITY // (NS or interpolate from a function) at current time tn
5630 * if (VARIABLE_VELOCITY)
5632 * get_interpolated_velocity();
5635 * SET VELOCITY TO LEVEL SET SOLVER
5638 * level_set.set_velocity(locally_relevant_solution_u,locally_relevant_solution_v);
5642 * ////////////////////////
5643 * GET LEVEL SET SOLUTION // (at tnp1)
5644 * ////////////////////////
5647 * level_set.nth_time_step();
5656 * time+=time_step; // time tnp1
5665 * if (get_output && time-(output_number)*output_time>=0)
5667 * level_set.get_unp1(locally_relevant_solution_phi);
5671 * pcout << "FINAL TIME T=" << time << std::endl;
5674 * int main(int argc, char *argv[])
5678 * using namespace dealii;
5679 * Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1);
5680 * deallog.depth_console (0);
5682 * unsigned int degree = 1;
5683 * TestLevelSet<2> multiphase(degree, degree);
5687 * catch (std::exception &exc)
5689 * std::cerr << std::endl << std::endl
5690 * << "----------------------------------------------------"
5692 * std::cerr << "Exception on processing: " << std::endl
5693 * << exc.what() << std::endl
5694 * << "Aborting!" << std::endl
5695 * << "----------------------------------------------------"
5701 * std::cerr << std::endl << std::endl
5702 * << "----------------------------------------------------"
5704 * std::cerr << "Unknown exception!" << std::endl
5705 * << "Aborting!" << std::endl
5706 * << "----------------------------------------------------"
5717<a name="ann-TestNavierStokes.cc"></a>
5718<h1>Annotated version of TestNavierStokes.cc</h1>
5724 * /* -----------------------------------------------------------------------------
5726 * * SPDX-License-Identifier: LGPL-2.1-or-later
5727 * * Copyright (C) 2016 Manuel Quezada de Luna
5729 * * This file is part of the deal.II code gallery.
5731 * * -----------------------------------------------------------------------------
5734 * #include <deal.II/base/quadrature_lib.h>
5735 * #include <deal.II/base/function.h>
5736 * #include <deal.II/lac/affine_constraints.h>
5737 * #include <deal.II/lac/vector.h>
5738 * #include <deal.II/lac/full_matrix.h>
5739 * #include <deal.II/lac/solver_cg.h>
5740 * #include <deal.II/lac/petsc_sparse_matrix.h>
5741 * #include <deal.II/lac/petsc_vector.h>
5742 * #include <deal.II/lac/petsc_solver.h>
5743 * #include <deal.II/lac/petsc_precondition.h>
5744 * #include <deal.II/grid/grid_generator.h>
5745 * #include <deal.II/grid/tria_accessor.h>
5746 * #include <deal.II/grid/tria_iterator.h>
5747 * #include <deal.II/dofs/dof_handler.h>
5748 * #include <deal.II/dofs/dof_accessor.h>
5749 * #include <deal.II/dofs/dof_tools.h>
5750 * #include <deal.II/fe/fe_values.h>
5751 * #include <deal.II/fe/fe_q.h>
5752 * #include <deal.II/numerics/vector_tools.h>
5753 * #include <deal.II/numerics/data_out.h>
5754 * #include <deal.II/numerics/error_estimator.h>
5755 * #include <deal.II/base/utilities.h>
5756 * #include <deal.II/base/conditional_ostream.h>
5757 * #include <deal.II/base/index_set.h>
5758 * #include <deal.II/lac/sparsity_tools.h>
5759 * #include <deal.II/distributed/tria.h>
5760 * #include <deal.II/distributed/grid_refinement.h>
5761 * #include <deal.II/lac/petsc_vector.h>
5762 * #include <deal.II/base/convergence_table.h>
5763 * #include <deal.II/base/timer.h>
5764 * #include <deal.II/base/parameter_handler.h>
5765 * #include <fstream>
5766 * #include <iostream>
5767 * #include <deal.II/grid/grid_tools.h>
5768 * #include <deal.II/fe/mapping_q.h>
5769 * #include <deal.II/base/function.h>
5771 * using namespace dealii;
5773 * #include "utilities_test_NS.cc"
5774 * #include "NavierStokesSolver.cc"
5778 * ///////////////////////////////////////////////////
5779 * /////////////////// MAIN CLASS ////////////////////
5780 * ///////////////////////////////////////////////////
5783 * template <int dim>
5784 * class TestNavierStokes
5787 * TestNavierStokes (const unsigned int degree_LS,
5788 * const unsigned int degree_U);
5789 * ~TestNavierStokes ();
5793 * void get_boundary_values_U(double t);
5794 * void fix_pressure();
5795 * void output_results();
5796 * void process_solution(const unsigned int cycle);
5798 * void initial_condition();
5799 * void init_constraints();
5801 * PETScWrappers::MPI::Vector locally_relevant_solution_rho;
5802 * PETScWrappers::MPI::Vector locally_relevant_solution_u;
5803 * PETScWrappers::MPI::Vector locally_relevant_solution_v;
5804 * PETScWrappers::MPI::Vector locally_relevant_solution_w;
5805 * PETScWrappers::MPI::Vector locally_relevant_solution_p;
5806 * PETScWrappers::MPI::Vector completely_distributed_solution_rho;
5807 * PETScWrappers::MPI::Vector completely_distributed_solution_u;
5808 * PETScWrappers::MPI::Vector completely_distributed_solution_v;
5809 * PETScWrappers::MPI::Vector completely_distributed_solution_w;
5810 * PETScWrappers::MPI::Vector completely_distributed_solution_p;
5812 * std::vector<unsigned int> boundary_values_id_u;
5813 * std::vector<unsigned int> boundary_values_id_v;
5814 * std::vector<unsigned int> boundary_values_id_w;
5815 * std::vector<double> boundary_values_u;
5816 * std::vector<double> boundary_values_v;
5817 * std::vector<double> boundary_values_w;
5824 * MPI_Comm mpi_communicator;
5825 * parallel::distributed::Triangulation<dim> triangulation;
5828 * DoFHandler<dim> dof_handler_LS;
5830 * IndexSet locally_owned_dofs_LS;
5831 * IndexSet locally_relevant_dofs_LS;
5834 * DoFHandler<dim> dof_handler_U;
5836 * IndexSet locally_owned_dofs_U;
5837 * IndexSet locally_relevant_dofs_U;
5839 * DoFHandler<dim> dof_handler_P;
5841 * IndexSet locally_owned_dofs_P;
5842 * IndexSet locally_relevant_dofs_P;
5844 * AffineConstraints<double> constraints;
5848 * TimerOutput timer;
5856 * double final_time;
5857 * unsigned int timestep_number;
5862 * unsigned int n_cycles;
5863 * unsigned int n_refinement;
5864 * unsigned int output_number;
5865 * double output_time;
5873 * ConditionalOStream pcout;
5874 * ConvergenceTable convergence_table;
5879 * template <int dim>
5880 * TestNavierStokes<dim>::TestNavierStokes (const unsigned int degree_LS,
5881 * const unsigned int degree_U)
5883 * mpi_communicator (MPI_COMM_WORLD),
5884 * triangulation (mpi_communicator,
5885 * typename Triangulation<dim>::MeshSmoothing
5886 * (Triangulation<dim>::smoothing_on_refinement |
5887 * Triangulation<dim>::smoothing_on_coarsening)),
5888 * degree_LS(degree_LS),
5889 * dof_handler_LS (triangulation),
5890 * fe_LS (degree_LS),
5891 * degree_U(degree_U),
5892 * dof_handler_U (triangulation),
5894 * dof_handler_P (triangulation),
5895 * fe_P (degree_U-1), //TODO: change this to be degree_Q-1
5898 * timer(std::cout, TimerOutput::summary, TimerOutput::wall_times),
5901 * pcout (std::cout,(Utilities::MPI::this_mpi_process(mpi_communicator)== 0))
5904 * template <int dim>
5905 * TestNavierStokes<dim>::~TestNavierStokes ()
5907 * dof_handler_LS.clear ();
5908 * dof_handler_U.clear ();
5909 * dof_handler_P.clear ();
5914 * /////////////////////////////////////
5915 * /////////////// SETUP ///////////////
5916 * /////////////////////////////////////
5919 * template <int dim>
5920 * void TestNavierStokes<dim>::setup()
5927 * dof_handler_LS.distribute_dofs (fe_LS);
5928 * locally_owned_dofs_LS = dof_handler_LS.locally_owned_dofs ();
5929 * locally_relevant_dofs_LS = DoFTools::extract_locally_relevant_dofs (dof_handler_LS);
5935 * dof_handler_U.distribute_dofs (fe_U);
5936 * locally_owned_dofs_U = dof_handler_U.locally_owned_dofs ();
5937 * locally_relevant_dofs_U = DoFTools::extract_locally_relevant_dofs (dof_handler_U);
5943 * dof_handler_P.distribute_dofs (fe_P);
5944 * locally_owned_dofs_P = dof_handler_P.locally_owned_dofs ();
5945 * locally_relevant_dofs_P = DoFTools::extract_locally_relevant_dofs (dof_handler_P);
5946 * init_constraints();
5949 * init vectors for rho
5952 * locally_relevant_solution_rho.reinit (locally_owned_dofs_LS,locally_relevant_dofs_LS,mpi_communicator);
5953 * locally_relevant_solution_rho = 0;
5954 * completely_distributed_solution_rho.reinit(locally_owned_dofs_LS,mpi_communicator);
5957 * init vectors for u
5960 * locally_relevant_solution_u.reinit (locally_owned_dofs_U,locally_relevant_dofs_U,mpi_communicator);
5961 * locally_relevant_solution_u = 0;
5962 * completely_distributed_solution_u.reinit(locally_owned_dofs_U,mpi_communicator);
5965 * init vectors for v
5968 * locally_relevant_solution_v.reinit (locally_owned_dofs_U,locally_relevant_dofs_U,mpi_communicator);
5969 * locally_relevant_solution_v = 0;
5970 * completely_distributed_solution_v.reinit(locally_owned_dofs_U,mpi_communicator);
5973 * init vectors for w
5976 * locally_relevant_solution_w.reinit (locally_owned_dofs_U,locally_relevant_dofs_U,mpi_communicator);
5977 * locally_relevant_solution_w = 0;
5978 * completely_distributed_solution_w.reinit(locally_owned_dofs_U,mpi_communicator);
5981 * init vectors for p
5984 * locally_relevant_solution_p.reinit(locally_owned_dofs_P,locally_relevant_dofs_P,mpi_communicator);
5985 * locally_relevant_solution_p = 0;
5986 * completely_distributed_solution_p.reinit(locally_owned_dofs_P,mpi_communicator);
5989 * template <int dim>
5990 * void TestNavierStokes<dim>::initial_condition()
5995 * Initial conditions
5996 * init condition for rho
5999 * completely_distributed_solution_rho = 0;
6000 * VectorTools::interpolate(dof_handler_LS,
6001 * RhoFunction<dim>(0),
6002 * completely_distributed_solution_rho);
6003 * constraints.distribute (completely_distributed_solution_rho);
6004 * locally_relevant_solution_rho = completely_distributed_solution_rho;
6007 * init condition for u
6010 * completely_distributed_solution_u = 0;
6011 * VectorTools::interpolate(dof_handler_U,
6012 * ExactSolution_and_BC_U<dim>(0,0),
6013 * completely_distributed_solution_u);
6014 * constraints.distribute (completely_distributed_solution_u);
6015 * locally_relevant_solution_u = completely_distributed_solution_u;
6018 * init condition for v
6021 * completely_distributed_solution_v = 0;
6022 * VectorTools::interpolate(dof_handler_U,
6023 * ExactSolution_and_BC_U<dim>(0,1),
6024 * completely_distributed_solution_v);
6025 * constraints.distribute (completely_distributed_solution_v);
6026 * locally_relevant_solution_v = completely_distributed_solution_v;
6029 * init condition for w
6034 * completely_distributed_solution_w = 0;
6035 * VectorTools::interpolate(dof_handler_U,
6036 * ExactSolution_and_BC_U<dim>(0,2),
6037 * completely_distributed_solution_w);
6038 * constraints.distribute (completely_distributed_solution_w);
6039 * locally_relevant_solution_w = completely_distributed_solution_w;
6043 * init condition for p
6046 * completely_distributed_solution_p = 0;
6047 * VectorTools::interpolate(dof_handler_P,
6048 * ExactSolution_p<dim>(0),
6049 * completely_distributed_solution_p);
6050 * constraints.distribute (completely_distributed_solution_p);
6051 * locally_relevant_solution_p = completely_distributed_solution_p;
6054 * template <int dim>
6055 * void TestNavierStokes<dim>::init_constraints()
6057 * constraints.clear ();
6058 * #if DEAL_II_VERSION_GTE(9, 6, 0)
6059 * constraints.reinit (locally_owned_dofs_LS, locally_relevant_dofs_LS);
6061 * constraints.reinit (locally_relevant_dofs_LS);
6063 * DoFTools::make_hanging_node_constraints (dof_handler_LS, constraints);
6064 * constraints.close ();
6068 * void TestNavierStokes<dim>::fix_pressure()
6072 * fix the constant in the pressure
6075 * completely_distributed_solution_p = locally_relevant_solution_p;
6076 * double mean_value = VectorTools::compute_mean_value(dof_handler_P,
6078 * locally_relevant_solution_p,
6081 * completely_distributed_solution_p.add(-mean_value+std::sin(1)*(std::cos(time)-cos(1+time)));
6083 * completely_distributed_solution_p.add(-mean_value+8*std::pow(std::sin(0.5),3)*std::sin(1.5+time));
6084 * locally_relevant_solution_p = completely_distributed_solution_p;
6087 * template <int dim>
6088 * void TestNavierStokes<dim>::output_results ()
6090 * DataOut<dim> data_out;
6091 * data_out.attach_dof_handler (dof_handler_U);
6092 * data_out.add_data_vector (locally_relevant_solution_u, "u");
6093 * data_out.add_data_vector (locally_relevant_solution_v, "v");
6094 * if (dim==3) data_out.add_data_vector (locally_relevant_solution_w, "w");
6096 * Vector<float> subdomain (triangulation.n_active_cells());
6097 * for (unsigned int i=0; i<subdomain.size(); ++i)
6098 * subdomain(i) = triangulation.locally_owned_subdomain();
6099 * data_out.add_data_vector (subdomain, "subdomain");
6101 * data_out.build_patches ();
6103 * const std::string filename = ("solution-" +
6104 * Utilities::int_to_string (output_number, 3) +
6106 * Utilities::int_to_string
6107 * (triangulation.locally_owned_subdomain(), 4));
6108 * std::ofstream output ((filename + ".vtu").c_str());
6109 * data_out.write_vtu (output);
6111 * if (Utilities::MPI::this_mpi_process(mpi_communicator) == 0)
6113 * std::vector<std::string> filenames;
6114 * for (unsigned int i=0;
6115 * i<Utilities::MPI::n_mpi_processes(mpi_communicator);
6117 * filenames.push_back ("solution-" +
6118 * Utilities::int_to_string (output_number, 3) +
6120 * Utilities::int_to_string (i, 4) +
6123 * std::ofstream master_output ((filename + ".pvtu").c_str());
6124 * data_out.write_pvtu_record (master_output, filenames);
6129 * template <int dim>
6130 * void TestNavierStokes<dim>::process_solution(const unsigned int cycle)
6132 * Vector<double> difference_per_cell (triangulation.n_active_cells());
6138 * VectorTools::integrate_difference (dof_handler_U,
6139 * locally_relevant_solution_u,
6140 * ExactSolution_and_BC_U<dim>(time,0),
6141 * difference_per_cell,
6142 * QGauss<dim>(degree_U+1),
6143 * VectorTools::L2_norm);
6144 * double u_L2_error = difference_per_cell.l2_norm();
6146 * std::sqrt(Utilities::MPI::sum(u_L2_error * u_L2_error, mpi_communicator));
6147 * VectorTools::integrate_difference (dof_handler_U,
6148 * locally_relevant_solution_u,
6149 * ExactSolution_and_BC_U<dim>(time,0),
6150 * difference_per_cell,
6151 * QGauss<dim>(degree_U+1),
6152 * VectorTools::H1_norm);
6153 * double u_H1_error = difference_per_cell.l2_norm();
6155 * std::sqrt(Utilities::MPI::sum(u_H1_error * u_H1_error, mpi_communicator));
6161 * VectorTools::integrate_difference (dof_handler_U,
6162 * locally_relevant_solution_v,
6163 * ExactSolution_and_BC_U<dim>(time,1),
6164 * difference_per_cell,
6165 * QGauss<dim>(degree_U+1),
6166 * VectorTools::L2_norm);
6167 * double v_L2_error = difference_per_cell.l2_norm();
6169 * std::sqrt(Utilities::MPI::sum(v_L2_error * v_L2_error,
6170 * mpi_communicator));
6171 * VectorTools::integrate_difference (dof_handler_U,
6172 * locally_relevant_solution_v,
6173 * ExactSolution_and_BC_U<dim>(time,1),
6174 * difference_per_cell,
6175 * QGauss<dim>(degree_U+1),
6176 * VectorTools::H1_norm);
6177 * double v_H1_error = difference_per_cell.l2_norm();
6179 * std::sqrt(Utilities::MPI::sum(v_H1_error *
6180 * v_H1_error, mpi_communicator));
6186 * double w_L2_error = 0;
6187 * double w_H1_error = 0;
6190 * VectorTools::integrate_difference (dof_handler_U,
6191 * locally_relevant_solution_w,
6192 * ExactSolution_and_BC_U<dim>(time,2),
6193 * difference_per_cell,
6194 * QGauss<dim>(degree_U+1),
6195 * VectorTools::L2_norm);
6196 * w_L2_error = difference_per_cell.l2_norm();
6198 * std::sqrt(Utilities::MPI::sum(w_L2_error * w_L2_error,
6199 * mpi_communicator));
6200 * VectorTools::integrate_difference (dof_handler_U,
6201 * locally_relevant_solution_w,
6202 * ExactSolution_and_BC_U<dim>(time,2),
6203 * difference_per_cell,
6204 * QGauss<dim>(degree_U+1),
6205 * VectorTools::H1_norm);
6206 * w_H1_error = difference_per_cell.l2_norm();
6208 * std::sqrt(Utilities::MPI::sum(w_H1_error *
6209 * w_H1_error, mpi_communicator));
6216 * VectorTools::integrate_difference (dof_handler_P,
6217 * locally_relevant_solution_p,
6218 * ExactSolution_p<dim>(time),
6219 * difference_per_cell,
6220 * QGauss<dim>(degree_U+1),
6221 * VectorTools::L2_norm);
6222 * double p_L2_error = difference_per_cell.l2_norm();
6224 * std::sqrt(Utilities::MPI::sum(p_L2_error * p_L2_error,
6225 * mpi_communicator));
6226 * VectorTools::integrate_difference (dof_handler_P,
6227 * locally_relevant_solution_p,
6228 * ExactSolution_p<dim>(time),
6229 * difference_per_cell,
6230 * QGauss<dim>(degree_U+1),
6231 * VectorTools::H1_norm);
6232 * double p_H1_error = difference_per_cell.l2_norm();
6234 * std::sqrt(Utilities::MPI::sum(p_H1_error * p_H1_error,
6235 * mpi_communicator));
6237 * const unsigned int n_active_cells=triangulation.n_active_cells();
6238 * const unsigned int n_dofs_U=dof_handler_U.n_dofs();
6239 * const unsigned int n_dofs_P=dof_handler_P.n_dofs();
6241 * convergence_table.add_value("cycle", cycle);
6242 * convergence_table.add_value("cells", n_active_cells);
6243 * convergence_table.add_value("dofs_U", n_dofs_U);
6244 * convergence_table.add_value("dofs_P", n_dofs_P);
6245 * convergence_table.add_value("dt", time_step);
6246 * convergence_table.add_value("u L2", u_L2_error);
6247 * convergence_table.add_value("u H1", u_H1_error);
6248 * convergence_table.add_value("v L2", v_L2_error);
6249 * convergence_table.add_value("v H1", v_H1_error);
6252 * convergence_table.add_value("w L2", w_L2_error);
6253 * convergence_table.add_value("w H1", w_H1_error);
6255 * convergence_table.add_value("p L2", p_L2_error);
6256 * convergence_table.add_value("p H1", p_H1_error);
6259 * template <int dim>
6260 * void TestNavierStokes<dim>::get_boundary_values_U(double t)
6262 * std::map<unsigned int, double> map_boundary_values_u;
6263 * std::map<unsigned int, double> map_boundary_values_v;
6265 * VectorTools::interpolate_boundary_values (dof_handler_U,0,ExactSolution_and_BC_U<dim>(t,0),map_boundary_values_u);
6266 * VectorTools::interpolate_boundary_values (dof_handler_U,0,ExactSolution_and_BC_U<dim>(t,1),map_boundary_values_v);
6268 * boundary_values_id_u.resize(map_boundary_values_u.size());
6269 * boundary_values_id_v.resize(map_boundary_values_v.size());
6270 * boundary_values_u.resize(map_boundary_values_u.size());
6271 * boundary_values_v.resize(map_boundary_values_v.size());
6272 * std::map<unsigned int,double>::const_iterator boundary_value_u =map_boundary_values_u.begin();
6273 * std::map<unsigned int,double>::const_iterator boundary_value_v =map_boundary_values_v.begin();
6276 * std::map<unsigned int, double> map_boundary_values_w;
6277 * VectorTools::interpolate_boundary_values (dof_handler_U,0,ExactSolution_and_BC_U<dim>(t,2),map_boundary_values_w);
6278 * boundary_values_id_w.resize(map_boundary_values_w.size());
6279 * boundary_values_w.resize(map_boundary_values_w.size());
6280 * std::map<unsigned int,double>::const_iterator boundary_value_w =map_boundary_values_w.begin();
6281 * for (int i=0; boundary_value_w !=map_boundary_values_w.end(); ++boundary_value_w, ++i)
6283 * boundary_values_id_w[i]=boundary_value_w->first;
6284 * boundary_values_w[i]=boundary_value_w->second;
6287 * for (int i=0; boundary_value_u !=map_boundary_values_u.end(); ++boundary_value_u, ++i)
6289 * boundary_values_id_u[i]=boundary_value_u->first;
6290 * boundary_values_u[i]=boundary_value_u->second;
6292 * for (int i=0; boundary_value_v !=map_boundary_values_v.end(); ++boundary_value_v, ++i)
6294 * boundary_values_id_v[i]=boundary_value_v->first;
6295 * boundary_values_v[i]=boundary_value_v->second;
6299 * template <int dim>
6300 * void TestNavierStokes<dim>::run()
6302 * if (Utilities::MPI::this_mpi_process(mpi_communicator)== 0)
6304 * std::cout << "***** CONVERGENCE TEST FOR NS *****" << std::endl;
6305 * std::cout << "DEGREE LS: " << degree_LS << std::endl;
6306 * std::cout << "DEGREE U: " << degree_U << std::endl;
6310 * PARAMETERS FOR THE NAVIER STOKES PROBLEM
6317 * ForceTerms<dim> force_function;
6318 * RhoFunction<dim> rho_function;
6319 * NuFunction<dim> nu_function;
6323 * bool get_output = false;
6324 * bool get_error = true;
6327 * for (unsigned int cycle=0; cycle<n_cycles; ++cycle)
6331 * GridGenerator::hyper_cube (triangulation);
6332 * triangulation.refine_global (n_refinement);
6334 * initial_condition();
6338 * triangulation.refine_global(1);
6340 * initial_condition();
6350 * NavierStokesSolver<dim> navier_stokes (degree_LS,
6358 * mpi_communicator);
6361 * set INITIAL CONDITION within TRANSPORT PROBLEM
6365 * navier_stokes.initial_condition(locally_relevant_solution_rho,
6366 * locally_relevant_solution_u,
6367 * locally_relevant_solution_v,
6368 * locally_relevant_solution_p);
6370 * navier_stokes.initial_condition(locally_relevant_solution_rho,
6371 * locally_relevant_solution_u,
6372 * locally_relevant_solution_v,
6373 * locally_relevant_solution_w,
6374 * locally_relevant_solution_p);
6376 * pcout << "Cycle " << cycle << ':
' << std::endl;
6377 * pcout << " Cycle " << cycle
6378 * << " Number of active cells: "
6379 * << triangulation.n_global_active_cells() << std::endl
6380 * << " Number of degrees of freedom (velocity): "
6381 * << dof_handler_U.n_dofs() << std::endl
6382 * << " min h=" << GridTools::minimal_cell_diameter(triangulation)/std::sqrt(2)/degree_U
6390 * timestep_number=0;
6392 * double time_step_backup=time_step;
6393 * while (time<final_time)
6395 * timestep_number++;
6403 * if (time+time_step > final_time-1E-10)
6405 * pcout << "FINAL TIME STEP..." << std::endl;
6406 * time_step_backup=time_step;
6407 * time_step=final_time-time;
6409 * pcout << "Time step " << timestep_number
6410 * << "\twith dt=" << time_step
6411 * << "\tat tn=" << time
6420 * force_function.set_time(time+time_step);
6423 * /////////////////////////////
6424 * DENSITY AND VISCOSITY FIELD
6425 * /////////////////////////////
6428 * rho_function.set_time(time+time_step);
6429 * nu_function.set_time(time+time_step);
6432 * /////////////////////
6433 * BOUNDARY CONDITIONS
6434 * /////////////////////
6437 * get_boundary_values_U(time+time_step);
6438 * if (dim==2) navier_stokes.set_boundary_conditions(boundary_values_id_u, boundary_values_id_v,
6439 * boundary_values_u, boundary_values_v);
6440 * else navier_stokes.set_boundary_conditions(boundary_values_id_u,
6441 * boundary_values_id_v,
6442 * boundary_values_id_w,
6443 * boundary_values_u, boundary_values_v, boundary_values_w);
6451 * navier_stokes.nth_time_step();
6453 * navier_stokes.get_velocity(locally_relevant_solution_u,locally_relevant_solution_v);
6455 * navier_stokes.get_velocity(locally_relevant_solution_u,
6456 * locally_relevant_solution_v,
6457 * locally_relevant_solution_w);
6458 * navier_stokes.get_pressure(locally_relevant_solution_p);
6485 * if (get_output && time-(output_number)*output_time>=1E-10)
6488 * pcout << "FINAL TIME: " << time << std::endl;
6489 * time_step=time_step_backup;
6491 * process_solution(cycle);
6495 * convergence_table.set_precision("u L2", 2);
6496 * convergence_table.set_precision("u H1", 2);
6497 * convergence_table.set_scientific("u L2",true);
6498 * convergence_table.set_scientific("u H1",true);
6500 * convergence_table.set_precision("v L2", 2);
6501 * convergence_table.set_precision("v H1", 2);
6502 * convergence_table.set_scientific("v L2",true);
6503 * convergence_table.set_scientific("v H1",true);
6507 * convergence_table.set_precision("w L2", 2);
6508 * convergence_table.set_precision("w H1", 2);
6509 * convergence_table.set_scientific("w L2",true);
6510 * convergence_table.set_scientific("w H1",true);
6513 * convergence_table.set_precision("p L2", 2);
6514 * convergence_table.set_precision("p H1", 2);
6515 * convergence_table.set_scientific("p L2",true);
6516 * convergence_table.set_scientific("p H1",true);
6518 * convergence_table.set_tex_format("cells","r");
6519 * convergence_table.set_tex_format("dofs_U","r");
6520 * convergence_table.set_tex_format("dofs_P","r");
6521 * convergence_table.set_tex_format("dt","r");
6523 * if (Utilities::MPI::this_mpi_process(mpi_communicator) == 0)
6525 * std::cout << std::endl;
6526 * convergence_table.write_text(std::cout);
6532 * int main(int argc, char *argv[])
6536 * using namespace dealii;
6537 * Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1);
6538 * deallog.depth_console (0);
6540 * unsigned int degree_LS = 1;
6541 * unsigned int degree_U = 2;
6542 * TestNavierStokes<2> test_navier_stokes(degree_LS, degree_U);
6543 * test_navier_stokes.run();
6547 * catch (std::exception &exc)
6549 * std::cerr << std::endl << std::endl
6550 * << "----------------------------------------------------"
6552 * std::cerr << "Exception on processing: " << std::endl
6553 * << exc.what() << std::endl
6554 * << "Aborting!" << std::endl
6555 * << "----------------------------------------------------"
6562 * std::cerr << std::endl << std::endl
6563 * << "----------------------------------------------------"
6565 * std::cerr << "Unknown exception!" << std::endl
6566 * << "Aborting!" << std::endl
6567 * << "----------------------------------------------------"
6577<a name="ann-clean.sh"></a>
6578<h1>Annotated version of clean.sh</h1>
6580rm -rf CMakeFiles CMakeCache.txt Makefile cmake_install.cmake *~
6581rm -f MultiPhase TestLevelSet TestNavierStokes
6588<a name="ann-utilities.cc"></a>
6589<h1>Annotated version of utilities.cc</h1>
6595 * /* -----------------------------------------------------------------------------
6597 * * SPDX-License-Identifier: LGPL-2.1-or-later
6598 * * Copyright (C) 2016 Manuel Quezada de Luna
6600 * * This file is part of the deal.II code gallery.
6602 * * -----------------------------------------------------------------------------
6607 * /////////////////////////////////////////////////
6608 * ////////////////// INITIAL PHI //////////////////
6609 * /////////////////////////////////////////////////
6612 * template <int dim>
6613 * class InitialPhi : public Function <dim>
6616 * InitialPhi (unsigned int PROBLEM, double sharpness=0.005) : Function<dim>(),
6617 * sharpness(sharpness),
6618 * PROBLEM(PROBLEM) {}
6619 * virtual double value (const Point<dim> &p, const unsigned int component=0) const override;
6621 * unsigned int PROBLEM;
6623 * template <int dim>
6624 * double InitialPhi<dim>::value (const Point<dim> &p,
6625 * const unsigned int) const
6629 * double pi=numbers::PI;
6631 * if (PROBLEM==FILLING_TANK)
6632 * return 0.5*(-std::tanh((y-0.3)/sharpness)*std::tanh((y-0.35)/sharpness)+1)
6633 * *(-std::tanh((x-0.02)/sharpness)+1)-1;
6634 * else if (PROBLEM==BREAKING_DAM)
6635 * return 0.5*(-std::tanh((x-0.35)/sharpness)*std::tanh((x-0.65)/sharpness)+1)
6636 * *(1-std::tanh((y-0.35)/sharpness))-1;
6637 * else if (PROBLEM==FALLING_DROP)
6642 * double r = std::sqrt(std::pow(x-x0,2)+std::pow(y-y0,2));
6643 * return 1-(std::tanh((r-r0)/sharpness)+std::tanh((y-0.3)/sharpness));
6645 * else if (PROBLEM==SMALL_WAVE_PERTURBATION)
6647 * double wave = 0.1*std::sin(pi*x)+0.25;
6648 * return -std::tanh((y-wave)/sharpness);
6652 * std::cout << "Error in type of PROBLEM" << std::endl;
6659 * ///////////////////////////////////////////////////
6660 * ////////////////// FORCE TERMS ///// //////////////
6661 * ///////////////////////////////////////////////////
6664 * template <int dim>
6665 * class ForceTerms : public Functions::ConstantFunction <dim>
6668 * ForceTerms (const std::vector<double> values) : Functions::ConstantFunction<dim>(values) {}
6673 * /////////////////////////////////////////////////
6674 * ////////////////// BOUNDARY PHI /////////////////
6675 * /////////////////////////////////////////////////
6678 * template <int dim>
6679 * class BoundaryPhi : public Functions::ConstantFunction <dim>
6682 * BoundaryPhi (const double value, const unsigned int n_components=1) : Functions::ConstantFunction<dim>(value,n_components) {}
6687 * //////////////////////////////////////////////////////
6688 * ////////////////// BOUNDARY VELOCITY /////////////////
6689 * //////////////////////////////////////////////////////
6692 * template <int dim>
6693 * class BoundaryU : public Function <dim>
6696 * BoundaryU (unsigned int PROBLEM, double t=0) : Function<dim>(), PROBLEM(PROBLEM) {this->set_time(t);}
6697 * virtual double value (const Point<dim> &p, const unsigned int component=0) const override;
6700 * template <int dim>
6701 * double BoundaryU<dim>::value (const Point<dim> &p, const unsigned int) const
6705 * //////////////////
6707 * //////////////////
6708 * boundary for filling the tank (inlet)
6714 * if (PROBLEM==FILLING_TANK)
6716 * if (x==0 && y>=0.3 && y<=0.35)
6723 * std::cout << "Error in PROBLEM definition" << std::endl;
6728 * template <int dim>
6729 * class BoundaryV : public Function <dim>
6732 * BoundaryV (unsigned int PROBLEM, double t=0) : Function<dim>(), PROBLEM(PROBLEM) {this->set_time(t);}
6733 * virtual double value (const Point<dim> &p, const unsigned int component=0) const override;
6734 * unsigned int PROBLEM;
6736 * template <int dim>
6737 * double BoundaryV<dim>::value (const Point<dim> &p, const unsigned int) const
6741 * boundary for filling the tank (outlet)
6746 * double return_value = 0;
6748 * if (PROBLEM==FILLING_TANK)
6750 * if (y==0.4 && x>=0.3 && x<=0.35)
6751 * return_value = 0.25;
6753 * return return_value;
6758 * ///////////////////////////////////////////////////
6759 * ///////////////// POST-PROCESSING /////////////////
6760 * ///////////////////////////////////////////////////
6763 * template <int dim>
6764 * class Postprocessor : public DataPostprocessorScalar <dim>
6767 * Postprocessor(double eps, double rho_air, double rho_fluid)
6769 * DataPostprocessorScalar<dim>("Density",update_values)
6772 * this->rho_air=rho_air;
6773 * this->rho_fluid=rho_fluid;
6778 * evaluate_scalar_field (const DataPostprocessorInputs::Scalar<dim> &input_data,
6779 * std::vector<Vector<double> > &computed_quantities) const override;
6787 * template <int dim>
6789 * Postprocessor<dim>::
6790 * evaluate_scalar_field (const DataPostprocessorInputs::Scalar<dim> &input_data,
6791 * std::vector<Vector<double> > &computed_quantities) const
6793 * const unsigned int n_quadrature_points = input_data.solution_values.size();
6794 * for (unsigned int q=0; q<n_quadrature_points; ++q)
6798 * double phi_value=input_data.solution_values[q];
6799 * if (phi_value > eps)
6801 * else if (phi_value < -eps)
6805 * rho_value = rho_fluid*(1+H)/2. + rho_air*(1-H)/2.;
6806 * computed_quantities[q] = rho_value;
6813<a name="ann-utilities_test_LS.cc"></a>
6814<h1>Annotated version of utilities_test_LS.cc</h1>
6820 * /* -----------------------------------------------------------------------------
6822 * * SPDX-License-Identifier: LGPL-2.1-or-later
6823 * * Copyright (C) 2016 Manuel Quezada de Luna
6825 * * This file is part of the deal.II code gallery.
6827 * * -----------------------------------------------------------------------------
6832 * ///////////////////////////////////////////////////
6833 * ////////////////// INITIAL PHI //////////////////
6834 * ///////////////////////////////////////////////////
6837 * template <int dim>
6838 * class InitialPhi : public Function <dim>
6841 * InitialPhi (unsigned int PROBLEM, double sharpness=0.005) : Function<dim>(),
6842 * sharpness(sharpness),
6843 * PROBLEM(PROBLEM) {}
6844 * virtual double value (const Point<dim> &p, const unsigned int component=0) const;
6846 * unsigned int PROBLEM;
6848 * template <int dim>
6849 * double InitialPhi<dim>::value (const Point<dim> &p,
6850 * const unsigned int) const
6854 * double return_value = -1.;
6856 * if (PROBLEM==CIRCULAR_ROTATION)
6861 * double r = std::sqrt(std::pow(x-x0,2)+std::pow(y-y0,2));
6862 * return_value = -std::tanh((r-r0)/sharpness);
6864 * else // (PROBLEM==DIAGONAL_ADVECTION)
6871 * r = std::sqrt(std::pow(x-x0,2)+std::pow(y-y0,2));
6876 * r = std::sqrt(std::pow(x-x0,2)+std::pow(y-y0,2)+std::pow(z-z0,2));
6878 * return_value = -std::tanh((r-r0)/sharpness);
6880 * return return_value;
6885 * /////////////////////////////////////////////////
6886 * ////////////////// BOUNDARY PHI /////////////////
6887 * /////////////////////////////////////////////////
6890 * template <int dim>
6891 * class BoundaryPhi : public Function <dim>
6894 * BoundaryPhi (double t=0)
6897 * {this->set_time(t);}
6898 * virtual double value (const Point<dim> &p, const unsigned int component=0) const;
6901 * template <int dim>
6902 * double BoundaryPhi<dim>::value (const Point<dim> &, const unsigned int) const
6909 * ///////////////////////////////////////////////////
6910 * ////////////////// EXACT VELOCITY /////////////////
6911 * ///////////////////////////////////////////////////
6914 * template <int dim>
6915 * class ExactU : public Function <dim>
6918 * ExactU (unsigned int PROBLEM, double time=0) : Function<dim>(), PROBLEM(PROBLEM), time(time) {}
6919 * virtual double value (const Point<dim> &p, const unsigned int component=0) const;
6920 * void set_time(double time) {this->time=time;};
6925 * template <int dim>
6926 * double ExactU<dim>::value (const Point<dim> &p, const unsigned int) const
6928 * if (PROBLEM==CIRCULAR_ROTATION)
6929 * return -2*numbers::PI*(p[1]-0.5);
6930 * else // (PROBLEM==DIAGONAL_ADVECTION)
6934 * template <int dim>
6935 * class ExactV : public Function <dim>
6938 * ExactV (unsigned int PROBLEM, double time=0) : Function<dim>(), PROBLEM(PROBLEM), time(time) {}
6939 * virtual double value (const Point<dim> &p, const unsigned int component=0) const;
6940 * void set_time(double time) {this->time=time;};
6941 * unsigned int PROBLEM;
6945 * template <int dim>
6946 * double ExactV<dim>::value (const Point<dim> &p, const unsigned int) const
6948 * if (PROBLEM==CIRCULAR_ROTATION)
6949 * return 2*numbers::PI*(p[0]-0.5);
6950 * else // (PROBLEM==DIAGONAL_ADVECTION)
6954 * template <int dim>
6955 * class ExactW : public Function <dim>
6958 * ExactW (unsigned int PROBLEM, double time=0) : Function<dim>(), PROBLEM(PROBLEM), time(time) {}
6959 * virtual double value (const Point<dim> &p, const unsigned int component=0) const;
6960 * void set_time(double time) {this->time=time;};
6961 * unsigned int PROBLEM;
6965 * template <int dim>
6966 * double ExactW<dim>::value (const Point<dim> &, const unsigned int) const
6970 * PROBLEM = 3D_DIAGONAL_ADVECTION
6979<a name="ann-utilities_test_NS.cc"></a>
6980<h1>Annotated version of utilities_test_NS.cc</h1>
6986 * /* -----------------------------------------------------------------------------
6988 * * SPDX-License-Identifier: LGPL-2.1-or-later
6989 * * Copyright (C) 2016 Manuel Quezada de Luna
6991 * * This file is part of the deal.II code gallery.
6993 * * -----------------------------------------------------------------------------
6998 * ///////////////////////////////////////////////////
6999 * ////////// EXACT SOLUTION RHO TO TEST NS //////////
7000 * ///////////////////////////////////////////////////
7003 * template <int dim>
7004 * class RhoFunction : public Function <dim>
7007 * RhoFunction (double t=0) : Function<dim>() {this->set_time(t);}
7008 * virtual double value (const Point<dim> &p, const unsigned int component=0) const;
7010 * template <int dim>
7011 * double RhoFunction<dim>::value (const Point<dim> &p,
7012 * const unsigned int) const
7014 * double t = this->get_time();
7015 * double return_value = 0;
7017 * return_value = std::pow(std::sin(p[0]+p[1]+t),2)+1;
7019 * return_value = std::pow(std::sin(p[0]+p[1]+p[2]+t),2)+1;
7020 * return return_value;
7023 * template <int dim>
7024 * class NuFunction : public Function <dim>
7027 * NuFunction (double t=0) : Function<dim>() {this->set_time(t);}
7028 * virtual double value (const Point<dim> &p, const unsigned int component=0) const;
7030 * template <int dim>
7031 * double NuFunction<dim>::value (const Point<dim> &, const unsigned int) const
7038 * //////////////////////////////////////////////////////////////
7039 * ///////////////// EXACT SOLUTION U to TEST NS ////////////////
7040 * //////////////////////////////////////////////////////////////
7043 * template <int dim>
7044 * class ExactSolution_and_BC_U : public Function <dim>
7047 * ExactSolution_and_BC_U (double t=0, int field=0)
7052 * this->set_time(t);
7054 * virtual double value (const Point<dim> &p, const unsigned int component=1) const;
7055 * virtual Tensor<1,dim> gradient (const Point<dim> &p, const unsigned int component=1) const;
7056 * virtual void set_field(int field) {this->field=field;}
7058 * unsigned int type_simulation;
7060 * template <int dim>
7061 * double ExactSolution_and_BC_U<dim>::value (const Point<dim> &p,
7062 * const unsigned int) const
7064 * double t = this->get_time();
7065 * double return_value = 0;
7066 * double Pi = numbers::PI;
7073 * return_value = std::sin(x)*std::sin(y+t);
7075 * return_value = std::cos(x)*std::cos(y+t);
7080 * return_value = std::cos(t)*std::cos(Pi*y)*std::cos(Pi*z)*std::sin(Pi*x);
7081 * else if (field == 1)
7082 * return_value = std::cos(t)*std::cos(Pi*x)*std::cos(Pi*z)*std::sin(Pi*y);
7084 * return_value = -2*std::cos(t)*std::cos(Pi*x)*std::cos(Pi*y)*std::sin(Pi*z);
7086 * return return_value;
7088 * template <int dim>
7089 * Tensor<1,dim> ExactSolution_and_BC_U<dim>::gradient (const Point<dim> &p,
7090 * const unsigned int) const
7094 * THIS IS USED JUST FOR TESTING NS
7097 * Tensor<1,dim> return_value;
7098 * double t = this->get_time();
7099 * double Pi = numbers::PI;
7106 * return_value[0] = std::cos(x)*std::sin(y+t);
7107 * return_value[1] = std::sin(x)*std::cos(y+t);
7111 * return_value[0] = -std::sin(x)*std::cos(y+t);
7112 * return_value[1] = -std::cos(x)*std::sin(y+t);
7119 * return_value[0] = Pi*std::cos(t)*std::cos(Pi*x)*std::cos(Pi*y)*std::cos(Pi*z);
7120 * return_value[1] = -(Pi*std::cos(t)*std::cos(Pi*z)*std::sin(Pi*x)*std::sin(Pi*y));
7121 * return_value[2] = -(Pi*std::cos(t)*std::cos(Pi*y)*std::sin(Pi*x)*std::sin(Pi*z));
7123 * else if (field == 1)
7125 * return_value[0] = -(Pi*std::cos(t)*std::cos(Pi*z)*std::sin(Pi*x)*std::sin(Pi*y));
7126 * return_value[1] = Pi*std::cos(t)*std::cos(Pi*x)*std::cos(Pi*y)*std::cos(Pi*z);
7127 * return_value[2] = -(Pi*std::cos(t)*std::cos(Pi*x)*std::sin(Pi*y)*std::sin(Pi*z));
7131 * return_value[0] = 2*Pi*std::cos(t)*std::cos(Pi*y)*std::sin(Pi*x)*std::sin(Pi*z);
7132 * return_value[1] = 2*Pi*std::cos(t)*std::cos(Pi*x)*std::sin(Pi*y)*std::sin(Pi*z);
7133 * return_value[2] = -2*Pi*std::cos(t)*std::cos(Pi*x)*std::cos(Pi*y)*std::cos(Pi*z);
7136 * return return_value;
7141 * ///////////////////////////////////////////////////
7142 * ///////// EXACT SOLUTION FOR p TO TEST NS /////////
7143 * ///////////////////////////////////////////////////
7146 * template <int dim>
7147 * class ExactSolution_p : public Function <dim>
7150 * ExactSolution_p (double t=0) : Function<dim>() {this->set_time(t);}
7151 * virtual double value (const Point<dim> &p, const unsigned int component=0) const;
7152 * virtual Tensor<1,dim> gradient (const Point<dim> &p, const unsigned int component = 0) const;
7155 * template <int dim>
7156 * double ExactSolution_p<dim>::value (const Point<dim> &p, const unsigned int) const
7158 * double t = this->get_time();
7159 * double return_value = 0;
7161 * return_value = std::cos(p[0])*std::sin(p[1]+t);
7163 * return_value = std::sin(p[0]+p[1]+p[2]+t);
7164 * return return_value;
7167 * template <int dim>
7168 * Tensor<1,dim> ExactSolution_p<dim>::gradient (const Point<dim> &p, const unsigned int) const
7170 * Tensor<1,dim> return_value;
7171 * double t = this->get_time();
7174 * return_value[0] = -std::sin(p[0])*std::sin(p[1]+t);
7175 * return_value[1] = std::cos(p[0])*std::cos(p[1]+t);
7179 * return_value[0] = std::cos(t+p[0]+p[1]+p[2]);
7180 * return_value[1] = std::cos(t+p[0]+p[1]+p[2]);
7181 * return_value[2] = std::cos(t+p[0]+p[1]+p[2]);
7183 * return return_value;
7188 * //////////////////////////////////////////////////////////////
7189 * ////////////////// FORCE TERMS to TEST NS ////////////////////
7190 * //////////////////////////////////////////////////////////////
7193 * template <int dim>
7194 * class ForceTerms : public Function <dim>
7197 * ForceTerms (double t=0)
7201 * this->set_time(t);
7204 * virtual void vector_value (const Point<dim> &p, Vector<double> &values) const;
7208 * template <int dim>
7209 * void ForceTerms<dim>::vector_value (const Point<dim> &p, Vector<double> &values) const
7214 * double t = this->get_time();
7215 * double Pi = numbers::PI;
7224 * values[0] = std::cos(t+y)*std::sin(x)*(1+std::pow(std::sin(t+x+y),2)) // time derivative
7225 * +2*nu*std::sin(x)*std::sin(t+y) // viscosity
7226 * +std::cos(x)*std::sin(x)*(1+std::pow(std::sin(t+x+y),2)) // non-linearity
7227 * -std::sin(x)*std::sin(y+t); // pressure
7233 * values[1] = -(std::cos(x)*std::sin(t+y)*(1+std::pow(std::sin(t+x+y),2))) // time derivative
7234 * +2*nu*std::cos(x)*std::cos(t+y) // viscosity
7235 * -(std::sin(2*(t+y))*(1+std::pow(std::sin(t+x+y),2)))/2. // non-linearity
7236 * +std::cos(x)*std::cos(y+t); // pressure
7247 * -(std::cos(Pi*y)*std::cos(Pi*z)*std::sin(t)*std::sin(Pi*x)*(1+std::pow(std::sin(t+x+y+z),2))) //time der.
7248 * +3*std::pow(Pi,2)*std::cos(t)*std::cos(Pi*y)*std::cos(Pi*z)*std::sin(Pi*x) //viscosity
7249 * -(Pi*std::pow(std::cos(t),2)*(-3+std::cos(2*(t+x+y+z)))*std::sin(2*Pi*x)*(std::cos(2*Pi*y)+std::pow(std::sin(Pi*z),2)))/4. //NL
7250 * +std::cos(t+x+y+z); // pressure
7252 * -(std::cos(Pi*x)*std::cos(Pi*z)*std::sin(t)*std::sin(Pi*y)*(1+std::pow(std::sin(t+x+y+z),2))) //time der
7253 * +3*std::pow(Pi,2)*std::cos(t)*std::cos(Pi*x)*std::cos(Pi*z)*std::sin(Pi*y) //viscosity
7254 * -(Pi*std::pow(std::cos(t),2)*(-3+std::cos(2*(t+x+y+z)))*std::sin(2*Pi*y)*(std::cos(2*Pi*x)+std::pow(std::sin(Pi*z),2)))/4. //NL
7255 * +std::cos(t+x+y+z); // pressure
7257 * 2*std::cos(Pi*x)*std::cos(Pi*y)*std::sin(t)*std::sin(Pi*z)*(1+std::pow(std::sin(t+x+y+z),2)) //time der
7258 * -6*std::pow(Pi,2)*std::cos(t)*std::cos(Pi*x)*std::cos(Pi*y)*std::sin(Pi*z) //viscosity
7259 * -(Pi*std::pow(std::cos(t),2)*(2+std::cos(2*Pi*x)+std::cos(2*Pi*y))*(-3+std::cos(2*(t+x+y+z)))*std::sin(2*Pi*z))/4. //NL
7260 * +std::cos(t+x+y+z); // pressure
void attach_dof_handler(const DoFHandler< dim, spacedim > &)
void subtract_set(const IndexSet &other)
@ smoothing_on_refinement
@ smoothing_on_coarsening
#define DEAL_II_VERSION_GTE(major, minor, subminor)
typename ActiveSelector::active_cell_iterator active_cell_iterator
void loop(IteratorType begin, std_cxx20::type_identity_t< IteratorType > end, DOFINFO &dinfo, INFOBOX &info, const std::function< void(std_cxx20::type_identity_t< DOFINFO > &, typename INFOBOX::CellInfo &)> &cell_worker, const std::function< void(std_cxx20::type_identity_t< DOFINFO > &, typename INFOBOX::CellInfo &)> &boundary_worker, const std::function< void(std_cxx20::type_identity_t< DOFINFO > &, std_cxx20::type_identity_t< DOFINFO > &, typename INFOBOX::CellInfo &, typename INFOBOX::CellInfo &)> &face_worker, AssemblerType &assembler, const LoopControl &lctrl=LoopControl())
void make_hanging_node_constraints(const DoFHandler< dim, spacedim > &dof_handler, AffineConstraints< number > &constraints)
void make_sparsity_pattern(const DoFHandler< dim, spacedim > &dof_handler, SparsityPatternBase &sparsity_pattern, const AffineConstraints< number > &constraints={}, const bool keep_constrained_dofs=true, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id)
@ update_values
Shape function values.
@ update_normal_vectors
Normal vectors.
@ update_JxW_values
Transformed quadrature weights.
@ update_gradients
Shape function gradients.
@ update_quadrature_points
Transformed quadrature points.
CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt K
void hyper_rectangle(Triangulation< dim, spacedim > &tria, const Point< dim > &p1, const Point< dim > &p2, const bool colorize=false)
void subdivided_hyper_rectangle(Triangulation< dim, spacedim > &tria, const std::vector< unsigned int > &repetitions, const Point< dim > &p1, const Point< dim > &p2, const bool colorize=false)
@ matrix
Contents is actually a matrix.
constexpr types::blas_int zero
SymmetricTensor< 2, dim, Number > C(const Tensor< 2, dim, Number > &F)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
VectorType::value_type * end(VectorType &V)
VectorType::value_type * begin(VectorType &V)
T sum(const T &t, const MPI_Comm mpi_communicator)
unsigned int n_mpi_processes(const MPI_Comm mpi_communicator)
T max(const T &t, const MPI_Comm mpi_communicator)
T min(const T &t, const MPI_Comm mpi_communicator)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
std::string compress(const std::string &input)
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
void run(const Iterator &begin, const std_cxx20::type_identity_t< Iterator > &end, Worker worker, Copier copier, const ScratchData &sample_scratch_data, const CopyData &sample_copy_data, const unsigned int queue_length, const unsigned int chunk_size)
void abort(const ExceptionBase &exc) noexcept
int(& functions)(const void *v1, const void *v2)
void assemble(const MeshWorker::DoFInfoBox< dim, DOFINFO > &dinfo, A *assembler)
::VectorizedArray< Number, width > log(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > pow(const ::VectorizedArray< Number, width > &, const Number p)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)