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 dealii+unsubscr...@googlegroups.com.
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;
}


Reply via email to