Skip to content

Commit 349de4d

Browse files
committed
Init Chorin-Temam projection
1 parent 3d2f5bf commit 349de4d

9 files changed

+5602
-3
lines changed
Lines changed: 324 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,324 @@
1+
/*! \addtogroup equations
2+
* @{
3+
*/
4+
5+
/**
6+
* Navier Stokes Equation using Chorin-Temam projection method
7+
*/
8+
9+
#ifndef _pidomus_navier_stokes_h_
10+
#define _pidomus_navier_stokes_h_
11+
12+
#include "pde_system_interface.h"
13+
14+
#include <deal.II/grid/filtered_iterator.h>
15+
16+
#include <deal.II/base/work_stream.h>
17+
18+
#include <deal.II/lac/solver_cg.h>
19+
#include <deal.II/lac/solver_gmres.h>
20+
21+
#include <deal2lkit/sacado_tools.h>
22+
#include <deal2lkit/parsed_preconditioner/amg.h>
23+
#include <deal2lkit/parsed_preconditioner/jacobi.h>
24+
25+
////////////////////////////////////////////////////////////////////////////////
26+
/// Navier Stokes interface:
27+
28+
template <int dim, int spacedim=dim, typename LAC=LATrilinos>
29+
class NavierStokes
30+
:
31+
public PDESystemInterface<dim,spacedim,NavierStokes<dim,spacedim,LAC>, LAC>
32+
{
33+
34+
public:
35+
~NavierStokes () {};
36+
NavierStokes ();
37+
38+
void declare_parameters (ParameterHandler &prm);
39+
40+
template <typename EnergyType, typename ResidualType>
41+
void
42+
energies_and_residuals(
43+
const typename DoFHandler<dim,spacedim>::active_cell_iterator &cell,
44+
FEValuesCache<dim,spacedim> &scratch,
45+
std::vector<EnergyType> &energies,
46+
std::vector<std::vector<ResidualType>> &residuals,
47+
bool compute_only_system_terms) const;
48+
49+
void
50+
compute_system_operators(
51+
const std::vector<shared_ptr<LATrilinos::BlockMatrix>>,
52+
LinearOperator<LATrilinos::VectorType> &,
53+
LinearOperator<LATrilinos::VectorType> &,
54+
LinearOperator<LATrilinos::VectorType> &) const;
55+
56+
void
57+
set_matrix_couplings(std::vector<std::string> &couplings) const;
58+
59+
private:
60+
61+
/**
62+
* AMG preconditioner for velocity-velocity matrix.
63+
*/
64+
mutable ParsedJacobiPreconditioner AMG_u;
65+
66+
/**
67+
* AMG preconditioner for velocity-velocity matrix.
68+
*/
69+
mutable ParsedJacobiPreconditioner AMG_v;
70+
71+
/**
72+
* AMG preconditioner for velocity-velocity matrix.
73+
*/
74+
mutable ParsedAMGPreconditioner AMG_p;
75+
76+
// PHYSICAL PARAMETERS:
77+
////////////////////////////////////////////
78+
79+
/**
80+
* Density
81+
*/
82+
double rho;
83+
84+
/**
85+
* Viscosity
86+
*/
87+
double nu;
88+
89+
double initial_delta_t;
90+
/**
91+
* Solver tolerance for CG
92+
*/
93+
double CG_solver_tolerance;
94+
95+
/**
96+
* Solver tolerance for GMRES
97+
*/
98+
double GMRES_solver_tolerance;
99+
};
100+
101+
template <int dim, int spacedim, typename LAC>
102+
NavierStokes<dim,spacedim, LAC>::
103+
NavierStokes()
104+
:
105+
PDESystemInterface<dim,spacedim,NavierStokes<dim,spacedim,LAC>, LAC>(
106+
"Navier Stokes Interface",
107+
dim+dim+1,
108+
1,
109+
"FESystem[FE_Q(2)^d-FE_Q(1)-FE_Q(2)^d]",
110+
(dim==3)?"v,v,v,p,u,u,u":"v,v,p,u,u",
111+
"1,0,1"),
112+
AMG_u("Prec for u", 1.4),
113+
AMG_v("Prec for v", 1.4),
114+
AMG_p("AMG for p")
115+
{
116+
this->init();
117+
}
118+
119+
template <int dim, int spacedim, typename LAC>
120+
void NavierStokes<dim,spacedim,LAC>::
121+
set_matrix_couplings(std::vector<std::string> &couplings) const
122+
{
123+
couplings[0] = "1,1,1;1,1,1;1,1,1";
124+
}
125+
126+
template <int dim, int spacedim, typename LAC>
127+
void NavierStokes<dim,spacedim,LAC>::
128+
declare_parameters (ParameterHandler &prm)
129+
{
130+
PDESystemInterface<dim,spacedim, NavierStokes<dim,spacedim,LAC>,LAC>::
131+
declare_parameters(prm);
132+
this->add_parameter(prm, &rho,
133+
"rho [kg m^3]", "1.0",
134+
Patterns::Double(0.0),
135+
"Density");
136+
this->add_parameter(prm, &nu,
137+
"nu [Pa s]", "1.0",
138+
Patterns::Double(0.0),
139+
"Viscosity");
140+
this->add_parameter(prm, &initial_delta_t,
141+
"initial delta t", "1e-1",
142+
Patterns::Double(0.0),
143+
"Initial Delta t");
144+
this->add_parameter(prm, &CG_solver_tolerance,
145+
"CG Solver tolerance", "1e-8",
146+
Patterns::Double(0.0));
147+
this->add_parameter(prm, &GMRES_solver_tolerance,
148+
"GMRES Solver tolerance", "1e-8",
149+
Patterns::Double(0.0));
150+
}
151+
152+
template <int dim, int spacedim, typename LAC>
153+
template <typename EnergyType, typename ResidualType>
154+
void
155+
NavierStokes<dim,spacedim,LAC>::
156+
energies_and_residuals(const typename DoFHandler<dim,spacedim>::active_cell_iterator &cell,
157+
FEValuesCache<dim,spacedim> &fe_cache,
158+
std::vector<EnergyType> &,
159+
std::vector<std::vector<ResidualType> > &residual,
160+
bool compute_only_system_terms) const
161+
{
162+
const FEValuesExtractors::Vector aux_velocity(0);
163+
const FEValuesExtractors::Scalar pressure(dim);
164+
const FEValuesExtractors::Vector velocity(dim+1);
165+
166+
ResidualType et = 0;
167+
double dummy = 0.0;
168+
169+
this->reinit (et, cell, fe_cache);
170+
171+
// Velocity:
172+
auto &us = fe_cache.get_values("solution", "u", velocity, et);
173+
auto &ues = fe_cache.get_values("explicit_solution", "ue", velocity, dummy);
174+
auto &grad_ues = fe_cache.get_gradients("explicit_solution", "grad_u", velocity, dummy);
175+
auto &div_us = fe_cache.get_divergences("solution", "div_u", velocity, et);
176+
auto &sym_grad_ues = fe_cache.get_symmetric_gradients("explicit_solution", "sym_grad_ue", velocity, dummy);
177+
178+
auto &vs = fe_cache.get_values("solution", "v", aux_velocity, et);
179+
auto &ves = fe_cache.get_values("explicit_solution", "ve", aux_velocity, dummy);
180+
auto &sym_grad_vs = fe_cache.get_symmetric_gradients("solution", "sym_grad_v", aux_velocity, et);
181+
auto &grad_vs = fe_cache.get_gradients("solution", "grad_v", aux_velocity, et);
182+
auto &div_vs = fe_cache.get_divergences("solution", "div_v", aux_velocity, et);
183+
184+
// Pressure:
185+
auto &ps = fe_cache.get_values("solution", "p", pressure, et);
186+
auto &pes = fe_cache.get_values("explicit_solution", "pe", pressure, dummy);
187+
auto &grad_ps = fe_cache.get_gradients("solution", "grad_p", pressure,et);
188+
auto &grad_pes = fe_cache.get_gradients("explicit_solution", "grad_pe", pressure,dummy);
189+
190+
191+
const unsigned int n_quad_points = us.size();
192+
auto &JxW = fe_cache.get_JxW_values();
193+
const auto delta_t = this->get_timestep() != this->get_timestep() ? initial_delta_t : this->get_timestep() ;
194+
auto &fev = fe_cache.get_current_fe_values();
195+
196+
for (unsigned int quad=0; quad<n_quad_points; ++quad)
197+
{
198+
// // Delta Pressure:
199+
// const ResidualType &dp = dps[quad];
200+
// const Tensor<1, dim, ResidualType> &grad_dp = grad_dps[quad];
201+
202+
// Pressure:
203+
const ResidualType &p = ps[quad];
204+
const double &pe = pes[quad];
205+
const Tensor<1, dim, ResidualType> &grad_p = grad_ps[quad];
206+
const Tensor<1, dim, double> &grad_pe = grad_pes[quad];
207+
208+
// Velocity:
209+
const Tensor<1, dim, ResidualType> &u = us[quad];
210+
const Tensor<1, dim, double> &ue = ues[quad];
211+
const Tensor<2, dim, double> &grad_ue = grad_ues[quad];
212+
const ResidualType &div_u = div_us[quad];
213+
214+
const Tensor<1, dim, ResidualType> &v = vs[quad];
215+
const Tensor<1, dim, double> vd = SacadoTools::to_double(v);
216+
const Tensor<2, dim, ResidualType> &grad_v = grad_vs[quad];
217+
const Tensor<2, dim, ResidualType> &sym_grad_v = sym_grad_vs[quad];
218+
const Tensor<2, dim, double> &sym_grad_ue = sym_grad_ues[quad];
219+
const Tensor<1, dim, double> &ve = ves[quad];
220+
const ResidualType &div_v = div_vs[quad];
221+
222+
for (unsigned int i=0; i<residual[0].size(); ++i)
223+
{
224+
// Velocity:
225+
auto v_test = fev[ aux_velocity ].value(i,quad);
226+
auto sym_grad_v_test = fev[ aux_velocity ].symmetric_gradient(i,quad);
227+
228+
229+
auto u_test = fev[ velocity ].value(i,quad);
230+
auto div_u_test = fev[ velocity ].divergence(i,quad);
231+
auto sym_grad_ue_test = fev[ velocity ].symmetric_gradient(i,quad);
232+
233+
// Pressure:
234+
auto p_test = fev[ pressure ].value(i,quad);
235+
auto grad_p_test = fev[ pressure ].gradient(i,quad);
236+
237+
ResidualType res = 0.0;
238+
239+
res += ((v-ue)/delta_t)*v_test;
240+
res += (ue * grad_ue )*v_test;
241+
res += nu * scalar_product( sym_grad_ue,
242+
sym_grad_ue_test);
243+
244+
/* res += (ue * grad_v )*v_test; */
245+
/* res += nu * scalar_product( sym_grad_v, */
246+
/* sym_grad_v_test); */
247+
248+
249+
res += grad_p*grad_p_test + (rho/delta_t)*(div_v * p_test);
250+
251+
// Updating of the solution:
252+
res += (u - v + (delta_t/rho) *grad_p)*u_test;
253+
254+
residual[0][i] += res * JxW[quad];
255+
}
256+
}
257+
(void)compute_only_system_terms;
258+
}
259+
260+
261+
template <int dim, int spacedim, typename LAC>
262+
void
263+
NavierStokes<dim,spacedim,LAC>::compute_system_operators(
264+
const std::vector<shared_ptr<LATrilinos::BlockMatrix>> matrices,
265+
LinearOperator<LATrilinos::VectorType> &system_op,
266+
LinearOperator<LATrilinos::VectorType> &prec_op,
267+
LinearOperator<LATrilinos::VectorType> &prec_op_finer) const
268+
{
269+
const unsigned int num_blocks = 3;
270+
typedef LATrilinos::VectorType::BlockType BVEC;
271+
typedef LATrilinos::VectorType VEC;
272+
273+
static ReductionControl solver_control(matrices[0]->m(), CG_solver_tolerance);
274+
static SolverCG<BVEC> solver_CG(solver_control);
275+
276+
const DoFHandler<dim,spacedim> &dh = this->get_dof_handler();
277+
const ParsedFiniteElement<dim,spacedim> fe = this->pfe;
278+
AMG_v.initialize_preconditioner( matrices[0]->block(0,0)); //, fe, dh);
279+
AMG_p.initialize_preconditioner<dim, spacedim>( matrices[0]->block(1,1), fe, dh);
280+
AMG_u.initialize_preconditioner( matrices[0]->block(2,2)); //, fe, dh);
281+
282+
////////////////////////////////////////////////////////////////////////////
283+
// SYSTEM MATRIX:
284+
////////////////////////////////////////////////////////////////////////////
285+
std::array<std::array<LinearOperator< BVEC >, num_blocks>, num_blocks> S;
286+
for (unsigned int i = 0; i<num_blocks; ++i)
287+
for (unsigned int j = 0; j<num_blocks; ++j)
288+
S[i][j] = linear_operator< BVEC >(matrices[0]->block(i,j) );
289+
system_op = BlockLinearOperator< VEC >(S);
290+
291+
292+
////////////////////////////////////////////////////////////////////////////
293+
// PRECONDITIONER MATRIX:
294+
////////////////////////////////////////////////////////////////////////////
295+
auto Av = linear_operator<BVEC>(matrices[0]->block(0,0));
296+
auto Av_inv = inverse_operator(Av, solver_CG, AMG_v);
297+
298+
auto Ap = linear_operator<BVEC>(matrices[0]->block(1,1));
299+
auto Ap_inv = inverse_operator(Ap, solver_CG, AMG_p);
300+
301+
auto Au = linear_operator<BVEC>(matrices[0]->block(2,2));
302+
auto Au_inv = inverse_operator(Au, solver_CG, AMG_u);
303+
304+
// Preconditioner
305+
//////////////////////////////
306+
307+
BlockLinearOperator<VEC> diag_inv
308+
= block_diagonal_operator<num_blocks, VEC>(
309+
{
310+
{
311+
Av_inv, Ap_inv, Au_inv
312+
}
313+
}
314+
);
315+
prec_op = diag_inv;
316+
317+
/* prec_op = block_forward_substitution( */
318+
/* BlockLinearOperator< VEC >(S), */
319+
/* diag_inv); */
320+
}
321+
322+
#endif
323+
324+
/*! @} */

source/pidomus.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ piDoMUS<dim, spacedim, LAC>::solve_jacobian_system(const typename LAC::VectorTyp
405405
if (we_are_parallel == false &&
406406
use_direct_solver == true)
407407
{
408-
408+
std::cout << "DIRETTO!" << std::endl;
409409
SparseDirectUMFPACK inverse;
410410
inverse.factorize((sMAT &) *matrices[0]);
411411
inverse.vmult((sVEC &)dst, (sVEC &)src);
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include "pidomus.h"
2+
#include "interfaces/navier_stokes-chorin-temam.h"
3+
#include "tests.h"
4+
5+
/**
6+
* Test: Navier Stokes interface.
7+
* Method: Direct
8+
* Problem: Non time depending Navier Stokes Equations
9+
* Exact solution:
10+
* \f[
11+
* u=\big( 2*(x^2)*y, -2*x*(y^2) \big)
12+
* \textrm{ and }p=xy;
13+
* \f]
14+
*/
15+
16+
using namespace dealii;
17+
int main (int argc, char *argv[])
18+
{
19+
20+
Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv,
21+
numbers::invalid_unsigned_int);
22+
23+
initlog();
24+
deallog.depth_file(1);
25+
26+
const int dim = 2;
27+
28+
NavierStokes<dim, dim, LADealII> energy;
29+
piDoMUS<dim, dim, LADealII> navier_stokes ("",energy);
30+
ParameterAcceptor::initialize(
31+
SOURCE_DIR "/parameters/navier_stokes_chorin-temam_00.prm",
32+
"used_parameters.prm");
33+
34+
navier_stokes.run ();
35+
36+
auto sol = navier_stokes.get_solution();
37+
for (unsigned int i = 0 ; i<sol.size(); ++i)
38+
{
39+
deallog << sol[i] << std::endl ;
40+
}
41+
42+
return 0;
43+
}

0 commit comments

Comments
 (0)