Hi
I am trying a different time integration approach using the generalized
alpha method rather then reposing with a velocity variable. I am also
switching to the BC handled by affine constraints.
I am not sure why the wave wont move through the mesh. I just see the BC at
the edge which quickly fades out in the tutorial.
Any hints or nudges would be appreciated code attached.
Matt
--
The deal.II project is located at http://www.dealii.org/
For mailing list/forum options, see
https://groups.google.com/d/forum/dealii?hl=en
---
You received this message because you are subscribed to the Google Groups
"deal.II User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/dealii/279806f2-2cf3-4c0d-84c6-ff44b8e4d7ebn%40googlegroups.com.
#include <deal.II/base/quadrature_lib.h>
#include <deal.II/base/function.h>
#include <deal.II/lac/vector.h>
#include <deal.II/lac/sparse_matrix.h>
#include <deal.II/lac/dynamic_sparsity_pattern.h>
#include <deal.II/lac/solver_cg.h>
#include <deal.II/lac/precondition.h>
#include <deal.II/lac/affine_constraints.h>
#include <deal.II/grid/tria.h>
#include <deal.II/grid/grid_generator.h>
#include <deal.II/dofs/dof_handler.h>
#include <deal.II/dofs/dof_tools.h>
#include <deal.II/fe/fe_q.h>
#include <deal.II/numerics/data_out.h>
#include <fstream>
#include <iostream>
#include <deal.II/numerics/vector_tools.h>
#include <deal.II/numerics/matrix_tools.h>
#include <deal.II/base/utilities.h>
namespace Final_Proj
{
using namespace dealii;
template <int dim>
class WaveEquation
{
public:
WaveEquation();
void run();
private:
void setup_system();
void solve();
void output_results() const;
Triangulation<dim> triangulation;
FE_Q<dim> fe;
DoFHandler<dim> dof_handler;
AffineConstraints<double> constraints;
SparsityPattern sparsity_pattern;
SparseMatrix<double> mass_matrix;
SparseMatrix<double> laplace_matrix;
SparseMatrix<double> system_matrix;
SparseMatrix<double> matrix_temp;
Vector<double> solution_u, solution_udot, solution_udotdot;
Vector<double> old_solution_u, old_solution_udot,
old_solution_udotdot;
Vector<double> system_rhs;
double time_step;
double time;
unsigned int timestep_number;
const double beta;
const double gamma;
const double alpha_f;
const double alpha_m;
const double wave_speed;
};
template <int dim>
class ExactSolution : public Function<dim>
{
public:
virtual double value(const Point<dim> &p, unsigned int component =
0) const override
{
(void)component;
double t = this-> get_time();
double exact = -1*std::exp(-1*dim*std::pow(M_PI,2)*t);
for (auto i = 0; i < dim; i++)
exact *= std::sin(M_PI*p[i]); // fix me!!!
return exact;
}
};
template <int dim>
class InitialValuesU : public Function<dim>
{
public:
virtual double value(const Point<dim> & /*p*/, const unsigned int
component = 0) const override
{
(void)component;
Assert(component == 0, ExcIndexRange(component, 0, 1));
return 0;
}
};
template <int dim>
class InitialValuesUdot : public Function<dim>
{
public:
virtual double value(const Point<dim> & /*p*/, const unsigned int
component = 0) const override
{
(void)component;
Assert(component == 0, ExcIndexRange(component, 0, 1));
return 0;
}
};
template <int dim>
class RightHandSide : public Function<dim>
{
public:
virtual double value(const Point<dim> & /*p*/, const unsigned int
component = 0) const override
{
(void)component;
Assert(component == 0, ExcIndexRange(component, 0, 1));
return 0;
}
};
template <int dim>
class BoundaryValuesU : public Function<dim>
{
public:
virtual double value(const Point<dim> & p, const unsigned int
component = 0) const override
{
(void)component;
Assert(component == 0, ExcIndexRange(component, 0, 1));
if ((this->get_time() <= 0.5) && (p[0] < 0) && (p[1] < 1. / 3)
&& (p[1] > -1. / 3))
return -std::sin(this->get_time() * 4 * numbers::PI);
else
return 0;
}
};
template <int dim>
WaveEquation<dim>::WaveEquation()
: fe(1)
, dof_handler(triangulation)
, time_step(1. / 64)
, time(time_step)
, timestep_number(1)
, beta(0.25) // unconditionally stable
, gamma(0.5) // unconditionally stable
, alpha_f(0.25)
, alpha_m(0.250)
, wave_speed(1)
{}
template <int dim>
void WaveEquation<dim>::setup_system()
{
GridGenerator::hyper_cube(triangulation, -1, 1);
triangulation.refine_global(7);
std::cout << "Number of active cells: " <<
triangulation.n_active_cells()
<< std::endl;
dof_handler.distribute_dofs(fe);
std::cout << "Number of degrees of freedom: " << dof_handler.n_dofs()
<< std::endl
<< std::endl;
DynamicSparsityPattern dsp(dof_handler.n_dofs(), dof_handler.n_dofs());
DoFTools::make_sparsity_pattern(dof_handler, dsp);
sparsity_pattern.copy_from(dsp);
mass_matrix.reinit(sparsity_pattern);
laplace_matrix.reinit(sparsity_pattern);
system_matrix.reinit(sparsity_pattern);
MatrixCreator::create_mass_matrix(dof_handler,
QGauss<dim>(fe.degree + 1),
mass_matrix);
MatrixCreator::create_laplace_matrix(dof_handler,
QGauss<dim>(fe.degree + 1),
laplace_matrix);
solution_u.reinit(dof_handler.n_dofs());
solution_udot.reinit(dof_handler.n_dofs());
solution_udotdot.reinit(dof_handler.n_dofs());
old_solution_u.reinit(dof_handler.n_dofs());
old_solution_udot.reinit(dof_handler.n_dofs());
old_solution_udotdot.reinit(dof_handler.n_dofs());
system_rhs.reinit(dof_handler.n_dofs());
}
template <int dim>
void WaveEquation<dim>::solve()
{
SolverControl solver_control(1000, 1e-8 * system_rhs.l2_norm());
SolverCG<Vector<double>> cg(solver_control);
cg.solve(system_matrix, solution_u, system_rhs, PreconditionIdentity());
constraints.distribute(solution_u);
std::cout << " u-equation: " << solver_control.last_step() << " CG
iterations." << std::endl;
}
template <int dim>
void WaveEquation<dim>::output_results() const
{
// Compute the pointwise maximum error:
Vector<double> max_error_per_cell(triangulation.n_active_cells());
{
ExactSolution<dim> exact_solution;
exact_solution.set_time(time);
MappingQGeneric<dim> mapping(1);
VectorTools::integrate_difference(mapping,
dof_handler,
solution_u,
exact_solution,
max_error_per_cell,
QIterated<dim>(QGauss<1>(2), 2),
VectorTools::NormType::Linfty_norm);
std::cout << "maximum error = " <<
*std::max_element(max_error_per_cell.begin(),max_error_per_cell.end()) <<
std::endl;
}
{
DataOut<dim> data_out;
data_out.attach_dof_handler(dof_handler);
data_out.add_data_vector(solution_u, "U");
data_out.add_data_vector(solution_udot, "V");
data_out.add_data_vector(solution_udotdot, "A");
data_out.add_data_vector(max_error_per_cell, "max_error_per_cell");
data_out.build_patches();
const std::string filename = "solution-" +
Utilities::int_to_string(timestep_number, 3) + ".vtu";
DataOutBase::VtkFlags vtk_flags;
vtk_flags.compression_level =
DataOutBase::VtkFlags::ZlibCompressionLevel::best_speed;
data_out.set_flags(vtk_flags);
std::ofstream output(filename);
data_out.write_vtu(output);
}
}
template <int dim>
void WaveEquation<dim>::run()
{
setup_system();
Vector<double> tmp(solution_u.size());
Vector<double> system_rhs(solution_u.size());
Vector<double> forcing_terms(solution_u.size());
for (; time <= 5; time += time_step, ++timestep_number)
{
BoundaryValuesU<dim> boundary_values_u_function;
boundary_values_u_function.set_time(time);
constraints.clear();
DoFTools::make_hanging_node_constraints(dof_handler, constraints);
VectorTools::interpolate_boundary_values(dof_handler,
0,
boundary_values_u_function,
constraints
);
constraints.close();
std::cout << "Time step " << timestep_number << " at t=" << time <<
std::endl;
// Building RHS
mass_matrix.vmult(tmp,old_solution_u);
// M*u_n
system_rhs.add((1-alpha_m)/(beta*time_step*time_step),tmp);
// M*(1-alpha_m)/(beta*delt^2)*u_n
mass_matrix.vmult(tmp,old_solution_udot);
//M*udot_n
system_rhs.add((1-alpha_m)/(beta*time_step),tmp);
// M*(1-alpha_m)/(beta*delt^2)*u_n +
M*(1-alpha_m)/(beta*delt)*udot_n
mass_matrix.vmult(tmp,old_solution_udotdot);
//M*udotdot_n
system_rhs.add((1+alpha_m-2*beta)/(2*beta),tmp);
// M*(1-alpha_m)/(beta*delt^2)*u_n +
M*(1-alpha_m)/(beta*delt)*udot_n + M*(1- alpha_m - 2*beta)/(2*beta)*udotdot)
laplace_matrix.vmult(tmp, old_solution_u);
//K*u_n
system_rhs.add(-1*wave_speed*wave_speed*alpha_f,tmp);
// - K*c^2 *alpha_f *u_n + M*(1-alpha_m)/(beta*delt^2)*u_n +
M*(1-alpha_m)/(beta*delt)*udot_n + M*(1- alpha_m - 2*beta)/(2*beta)*udotdot
RightHandSide<dim> rhs_function;
rhs_function.set_time(time);
VectorTools::create_right_hand_side(dof_handler,
QGauss<dim>(fe.degree + 1),
rhs_function,
forcing_terms,
constraints);
//
system_rhs.add((1-alpha_f),forcing_terms);
system_rhs.add(alpha_f,forcing_terms);
// F - K*c^2 *alpha_f *u_n + M*(1-alpha_m)/(beta*delt^2)*u_n +
M*(1-alpha_m)/(beta*delt)*udot_n + M*(1- alpha_m - 2*beta)/(2*beta)*udotdot
// Buidling system matrix
system_matrix.copy_from(mass_matrix);
// M
system_matrix *= (1-alpha_m)/(beta*time_step*time_step);
// M*(1-alpha_m)/(beta*delt^2)
system_matrix.add(wave_speed*wave_speed*(1-
alpha_f),laplace_matrix);
// M*(1-alpha_m)/(beta*delt^2) + c^2 * (1-alpha_f)*K
constraints.condense(system_matrix,system_rhs);
solve();
//solution_udot = gamma/(beta*time_step)*(solution_u-
old_solution_u) -
// (gamma -beta)/beta*old_solution_udot -
//
(gamma-2*beta)/(2*beta)*time_step*old_solution_udotdot;
solution_udot = solution_u;
solution_udot.sadd(gamma/(beta*time_step),-1*gamma/(beta*time_step),old_solution_u);
solution_udot.add(-1*(gamma -beta)/beta,old_solution_udot);
solution_udot.add(-1*(gamma-2*beta)/(2*beta)*time_step,old_solution_udotdot);
//solution_udotdot = 1/(beta*time_step*time_step)*(solution_u-
old_solution_u) -
// 1/(beta*time_step)*old_solution_udot -
// (1-2*beta)/(2*beta)*old_solution_udotdot;
solution_udotdot = solution_u;
solution_udotdot.sadd(1/(beta*time_step*time_step),-1/(beta*time_step*time_step),
old_solution_u);
solution_udotdot.add(-1/(beta*time_step)/beta,old_solution_udot);
solution_udotdot.add((1-2*beta)/(2*beta),old_solution_udotdot);
std::cout << " Total energy: " <<
(mass_matrix.matrix_norm_square(solution_udot) +
laplace_matrix.matrix_norm_square(solution_u)) / 2 << std::endl;
output_results();
old_solution_u = solution_u;
old_solution_udot = solution_udot;
old_solution_udotdot = solution_udotdot;
}
}
}
int main()
{
try
{
using namespace Final_Proj;
WaveEquation<2> wave_equation_solver;
wave_equation_solver.run();
}
catch (std::exception &exc)
{
std::cerr << std::endl
<< std::endl
<< "----------------------------------------------------"
<< std::endl;
std::cerr << "Exception on processing: " << std::endl
<< exc.what() << std::endl
<< "Aborting!" << std::endl
<< "----------------------------------------------------"
<< std::endl;
return 1;
}
catch (...)
{
std::cerr << std::endl
<< std::endl
<< "----------------------------------------------------"
<< std::endl;
std::cerr << "Unknown exception!" << std::endl
<< "Aborting!" << std::endl
<< "----------------------------------------------------"
<< std::endl;
return 1;
}
return 0;
}