6 void Phaseflow<dim>::setup_system()
9 this->dof_handler.distribute_dofs(this->fe);
11 DoFRenumbering::component_wise(this->dof_handler);
13 std::cout << std::endl
14 <<
"==========================================="
16 <<
"Number of active cells: " << this->triangulation.n_active_cells()
18 <<
"Number of degrees of freedom: " << this->dof_handler.n_dofs()
22 this->constraints.clear();
24 DoFTools::make_hanging_node_constraints(
28 this->constraints.close();
30 DynamicSparsityPattern dsp(this->dof_handler.n_dofs());
32 DoFTools::make_sparsity_pattern(
38 this->sparsity_pattern.copy_from(dsp);
40 this->system_matrix.reinit(this->sparsity_pattern);
42 this->solution.reinit(this->dof_handler.n_dofs());
44 this->newton_residual.reinit(this->dof_handler.n_dofs());
46 this->newton_solution.reinit(this->dof_handler.n_dofs());
48 this->old_solution.reinit(this->dof_handler.n_dofs());
50 this->old_newton_solution.reinit(this->dof_handler.n_dofs());
52 this->system_rhs.reinit(this->dof_handler.n_dofs());
91 void Phaseflow<dim>::assemble_system()
93 this->system_matrix = 0.;
95 this->system_rhs = 0.;
100 const double PENALTY = 1.e-7;
110 for (
unsigned int i = 0; i < dim; ++i)
112 g[i] = this->params.physics.gravity[i];
115 const double mu_l = this->params.physics.liquid_dynamic_viscosity;
120 auto f_B = [Ra, Pr, Re, g](
const double _theta)
122 return _theta*Ra/(Pr*Re*Re)*g;
128 const Tensor<1, dim> df_B_over_dtheta(Ra/(Pr*Re*Re)*g);
135 const Tensor<2, dim> _gradu,
136 const Tensor<2, dim> _gradv)
139 const Tensor<2, dim> _gradw)
141 return 0.5*(_gradw + transpose(_gradw));
144 return 2.*_mu*scalar_product(D(_gradu), D(_gradv));
155 const Tensor<1, dim> _w,
156 const Tensor<2, dim> _gradz,
157 const Tensor<1, dim> _v)
159 return (_v*_gradz)*_w;
168 FEValues<dim> fe_values(
171 update_values | update_gradients | update_quadrature_points | update_JxW_values);
173 const unsigned int dofs_per_cell = this->fe.dofs_per_cell;
175 const unsigned int n_quad_points = quadrature_formula.size();
177 FullMatrix<double> local_matrix(dofs_per_cell, dofs_per_cell);
179 Vector<double> local_rhs(dofs_per_cell);
181 std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
183 std::vector<Tensor<1,dim>> old_velocity_values(n_quad_points);
185 std::vector<double> old_pressure_values(n_quad_points);
187 std::vector<double> old_temperature_values(n_quad_points);
189 std::vector<Tensor<1,dim>> old_newton_velocity_values(n_quad_points);
191 std::vector<double> old_newton_pressure_values(n_quad_points);
193 std::vector<double> old_newton_temperature_values(n_quad_points);
195 std::vector<Tensor<2,dim>> old_newton_velocity_gradients(n_quad_points);
197 std::vector<Tensor<1,dim>> old_newton_temperature_gradients(n_quad_points);
199 std::vector<double> old_newton_velocity_divergences(n_quad_points);
201 std::vector<Vector<double>> source_values(n_quad_points, Vector<double>(dim + 2));
203 this->source_function.set_time(this->new_time);
205 typename DoFHandler<dim>::active_cell_iterator
206 cell = this->dof_handler.begin_active(),
207 endc = this->dof_handler.end();
213 const double deltat = this->time_step_size;
215 const double gamma = PENALTY;
217 for (; cell != endc; ++cell)
219 fe_values.reinit(cell);
221 fe_values[this->velocity_extractor].get_function_values(
223 old_velocity_values);
225 fe_values[this->pressure_extractor].get_function_values(
227 old_pressure_values);
229 fe_values[this->temperature_extractor].get_function_values(
231 old_temperature_values);
233 fe_values[this->velocity_extractor].get_function_values(
234 this->old_newton_solution,
235 old_newton_velocity_values);
237 fe_values[this->pressure_extractor].get_function_values(
238 this->old_newton_solution,
239 old_newton_pressure_values);
241 fe_values[this->temperature_extractor].get_function_values(
242 this->old_newton_solution,
243 old_newton_temperature_values);
245 fe_values[this->temperature_extractor].get_function_gradients(
246 this->old_newton_solution,
247 old_newton_temperature_gradients);
249 fe_values[this->velocity_extractor].get_function_gradients(
250 this->old_newton_solution,
251 old_newton_velocity_gradients);
253 fe_values[this->velocity_extractor].get_function_divergences(
254 this->old_newton_solution,
255 old_newton_velocity_divergences);
257 std::vector<Tensor<1, dim>> velocity_fe_values(dofs_per_cell);
258 std::vector<double> pressure_fe_values(dofs_per_cell);
259 std::vector<double> temperature_fe_values(dofs_per_cell);
260 std::vector<Tensor<1, dim>> grad_temperature_fe_values(dofs_per_cell);
261 std::vector<Tensor<2, dim>> grad_velocity_fe_values(dofs_per_cell);
262 std::vector<double> div_velocity_fe_values(dofs_per_cell);
268 this->source_function.vector_value_list(
269 fe_values.get_quadrature_points(),
272 for (
unsigned int quad = 0; quad< n_quad_points; ++quad)
275 const Tensor<1, dim> u_n = old_velocity_values[quad];
276 const double theta_n = old_temperature_values[quad];
278 const Tensor<1, dim> u_k = old_newton_velocity_values[quad];
279 const double p_k = old_newton_pressure_values[quad];
280 const double theta_k = old_newton_temperature_values[quad];
282 const Tensor<1, dim> gradtheta_k = old_newton_temperature_gradients[quad];
283 const Tensor<2, dim> gradu_k = old_newton_velocity_gradients[quad];
284 const double divu_k = old_newton_velocity_divergences[quad];
288 for (
unsigned int d = 0; d < dim; ++d)
290 s_u[d] = source_values[quad][d];
293 const double s_p = source_values[quad][dim];
295 const double s_theta = source_values[quad][dim+1];
297 for (
unsigned int dof = 0; dof < dofs_per_cell; ++dof)
299 velocity_fe_values[dof] = fe_values[this->velocity_extractor].value(dof, quad);
300 pressure_fe_values[dof] = fe_values[this->pressure_extractor].value(dof, quad);
301 temperature_fe_values[dof] = fe_values[this->temperature_extractor].value(dof, quad);
302 grad_temperature_fe_values[dof] = fe_values[this->temperature_extractor].gradient(dof, quad);
303 grad_velocity_fe_values[dof] = fe_values[this->velocity_extractor].gradient(dof, quad);
304 div_velocity_fe_values[dof] = fe_values[this->velocity_extractor].divergence(dof, quad);
307 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
310 const Tensor<1, dim> v = velocity_fe_values[i];
311 const double q = pressure_fe_values[i];
312 const double phi = temperature_fe_values[i];
313 const Tensor<1, dim> gradphi = grad_temperature_fe_values[i];
314 const Tensor<2, dim> gradv = grad_velocity_fe_values[i];
315 const double divv = div_velocity_fe_values[i];
322 for (
unsigned int j = 0; j< dofs_per_cell; ++j)
324 const Tensor<1, dim> u_w = velocity_fe_values[j];
325 const double p_w = pressure_fe_values[j];
326 const double theta_w = temperature_fe_values[j];
327 const Tensor<1, dim> gradtheta_w = grad_temperature_fe_values[j];
328 const Tensor<2, dim> gradu_w = grad_velocity_fe_values[j];
329 const double divu_w = div_velocity_fe_values[j];
331 local_matrix(i,j) += (
332 b(divu_w, q) - gamma*p_w*q
333 + scalar_product(u_w, v)/deltat + c(u_w, gradu_k, v) + c(u_k, gradu_w, v) + a(mu_l, gradu_w, gradv) + b(divv, p_w)
334 + scalar_product(theta_w*df_B_over_dtheta, v)
335 + theta_w*phi/deltat - scalar_product(u_k, gradphi)*theta_w - scalar_product(u_w, gradphi)*theta_k + scalar_product(K/Pr*gradtheta_w, gradphi)
336 )*fe_values.JxW(quad);
341 b(divu_k, q) - gamma*p_k*q
342 + scalar_product(u_k - u_n, v)/deltat + c(u_k, gradu_k, v) + a(mu_l, gradu_k, gradv) + b(divv, p_k)
343 + scalar_product(f_B(theta_k), v)
344 + (theta_k - theta_n)*phi/deltat - scalar_product(u_k, gradphi)*theta_k + scalar_product(K/Pr*gradtheta_k, gradphi)
345 + s_p*q + scalar_product(s_u, v) + s_theta*phi
346 )*fe_values.JxW(quad);
353 cell->get_dof_indices(local_dof_indices);
355 this->constraints.distribute_local_to_global(
356 local_matrix, local_rhs, local_dof_indices,
357 this->system_matrix, this->system_rhs);
364 void Phaseflow<dim>::interpolate_boundary_values(
365 Function<dim>*
function,
366 std::map<types::global_dof_index, double> &boundary_values)
const
368 for (
unsigned int ib = 0; ib < this->params.boundary_conditions.strong_boundaries.size(); ++ib)
370 unsigned int b = this->params.boundary_conditions.strong_boundaries[ib];
372 auto mask = this->params.boundary_conditions.strong_masks[b];
376 if (std::find(mask.begin(), mask.end(), field_name) == mask.end())
384 if (field_name ==
"velocity")
386 VectorTools::interpolate_boundary_values(
387 this->dof_handler, b, *
function, boundary_values,
388 this->fe.component_mask(this->velocity_extractor));
390 else if (field_name ==
"pressure")
392 VectorTools::interpolate_boundary_values(
393 this->dof_handler, b, *
function, boundary_values,
394 this->fe.component_mask(this->pressure_extractor));
396 else if (field_name ==
"temperature")
398 VectorTools::interpolate_boundary_values(
399 this->dof_handler, b, *
function, boundary_values,
400 this->fe.component_mask(this->temperature_extractor));
415 void Phaseflow<dim>::apply_boundary_values_and_constraints()
423 std::map<types::global_dof_index, double> residual_boundary_values, boundary_values, new_boundary_values;
431 Functions::FEFieldFunction<dim> solution_field_function(this->dof_handler, this->solution);
433 this->interpolate_boundary_values(&solution_field_function, boundary_values);
435 this->boundary_function.set_time(this->new_time);
437 this->interpolate_boundary_values(&this->boundary_function, new_boundary_values);
439 for (
auto m: new_boundary_values)
441 residual_boundary_values.insert(m);
443 residual_boundary_values[m.first] -= boundary_values[m.first];
446 MatrixTools::apply_boundary_values(
447 residual_boundary_values,
449 this->newton_residual,
460 void Phaseflow<dim>::solve_linear_system()
467 SparseDirectUMFPACK A_inv;
469 A_inv.initialize(this->system_matrix);
471 A_inv.vmult(this->newton_residual, this->system_rhs);
473 this->constraints.distribute(this->newton_residual);
475 std::cout <<
"Solved linear system" << std::endl;
const double LIQUID_CONDUCTIVITY
Definition: pf_global_parameters.h:20
const unsigned int SCALAR_DEGREE
Definition: pf_global_parameters.h:22
const double REYNOLDS_NUMBER
Definition: pf_global_parameters.h:16
std::vector< std::string > FIELD_NAMES({"velocity","pressure","temperature"})
void write_linear_system(SparseMatrix< double > &A, Vector< double > &b)
Definition: output.h:53
const double SOLID_CONDUCTIVITY
Definition: pf_global_parameters.h:18
const bool WRITE_LINEAR_SYSTEM
Definition: pf_global_parameters.h:26
const double RAYLEIGH_NUMBER
Definition: pf_global_parameters.h:12
const double PRANDTL_NUMBER
Definition: pf_global_parameters.h:14