Sure, attached is a *.cpp file that should run. The cout statement on line 87 prints non-zero values for `old_solution` but the cout statement online 92 always prints zero.
On Thursday, January 30, 2020 at 10:49:18 AM UTC-5, Wolfgang Bangerth wrote: > > On 1/30/20 8:45 AM, Andrew Davis wrote: > > I thought the same thing---that 'old_solution' would be a zero > vector---but > > when I add the line `std::cout << old_solution << std::endl;` in the > function > > IntegrateCell<dim>::operator() (just after the `get_function_values' > call in > > the original post) prints a non-zero vector that I expect. > > That does not sound credible to me. Can you construct a small example that > does exactly that? I.e., print out, for example, the l2-norm of > old_solution > right before the call to fe_values.get_function_values(), and the l2-norm > of > old_solution_values right after. > > Best > W. > > -- > ------------------------------------------------------------------------ > Wolfgang Bangerth email: bang...@colostate.edu > <javascript:> > www: http://www.math.colostate.edu/~bangerth/ > > -- 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/4dd7f499-1eeb-41b2-bed4-d715354007d7%40googlegroups.com.
#include <iostream> #include <fstream> #include <deal.II/base/quadrature_lib.h> #include <deal.II/base/function.h> #include <deal.II/lac/vector.h> #include <deal.II/lac/dynamic_sparsity_pattern.h> #include <deal.II/lac/sparse_matrix.h> #include <deal.II/lac/solver_richardson.h> #include <deal.II/lac/precondition_block.h> #include <deal.II/grid/tria.h> #include <deal.II/grid/grid_generator.h> #include <deal.II/grid/grid_out.h> #include <deal.II/grid/grid_refinement.h> #include <deal.II/grid/tria_accessor.h> #include <deal.II/grid/tria_iterator.h> #include <deal.II/fe/fe_values.h> #include <deal.II/fe/mapping_q1.h> #include <deal.II/fe/fe_dgq.h> #include <deal.II/dofs/dof_handler.h> #include <deal.II/dofs/dof_accessor.h> #include <deal.II/dofs/dof_tools.h> #include <deal.II/numerics/vector_tools.h> #include <deal.II/numerics/data_out.h> #include <deal.II/numerics/derivative_approximation.h> #include <deal.II/meshworker/dof_info.h> #include <deal.II/meshworker/integration_info.h> #include <deal.II/meshworker/simple.h> #include <deal.II/meshworker/loop.h> using namespace dealii; /// The initial conditions for the mass template<unsigned int dim> class InitialConditionMass : public dealii::Function<dim> { public: InitialConditionMass() = default; virtual ~InitialConditionMass() = default; virtual double value(dealii::Point<dim> const& p, const unsigned int component=0) const override; private: }; template<unsigned int dim> double InitialConditionMass<dim>::value(dealii::Point<dim> const& p, const unsigned int component) const { (void)component; Assert(component==0, ExcIndexRange(component, 0, 1)); return p(0); } template<unsigned int dim> class IntegrateCell { public: IntegrateCell(dealii::Vector<double> const& old_solution); virtual ~IntegrateCell() = default; void operator()(dealii::MeshWorker::DoFInfo<dim>& dinfo, dealii::MeshWorker::IntegrationInfo<dim>& info) const; private: /// Store a constant reference to the old solution const dealii::Vector<double>& old_solution; }; template<unsigned int dim> IntegrateCell<dim>::IntegrateCell(Vector<double> const& old_solution) : old_solution(old_solution) {} template<unsigned int dim> void IntegrateCell<dim>::operator()(MeshWorker::DoFInfo<dim>& dinfo, MeshWorker::IntegrationInfo<dim>& info) const { const FEValuesBase<dim>& feValues = info.fe_values(); // get the values of the old solution std::vector<double> old_solution_values(feValues.n_quadrature_points); feValues.get_function_values(old_solution, old_solution_values); //std::cout << "old_solution: " << old_solution.l2_norm() << std::endl; std::cout << "old_solution: " << old_solution << std::endl; // loop over the quadrature points and compute the advection vector at the current point for( unsigned int point=0; point<feValues.n_quadrature_points; ++point ) { std::cout << "point: " << feValues.quadrature_point(point) << std::endl; std::cout << "value: " << old_solution_values[point] << std::endl; } } /// The advection problem class template<unsigned int dim> class AdvectionProblem { public: /// Default constructor AdvectionProblem(); virtual ~AdvectionProblem() = default; void SetupSystem(); void AssembleSystem(); void Run(); private: /// Set up the initial condition /** @param[in] vec Set the intial condition onto this vector */ void SetInitialCondition(dealii::Vector<double>& vec); /// Globally refine the mesh /** @param[in] nrefine The number of global refinements */ void InitializeGrid(unsigned int const nrefine); using DoFInfo = dealii::MeshWorker::DoFInfo<dim>; using CellInfo = dealii::MeshWorker::IntegrationInfo<dim>; dealii::Triangulation<dim> triangulation; const dealii::MappingQ1<dim> mapping; dealii::FE_DGQ<dim> fe; dealii::DoFHandler<dim> dofHandler; dealii::AffineConstraints<double> constraints; dealii::SparsityPattern sparsityPattern; dealii::SparseMatrix<double> systemMatrix; /// The solution to the advection equation at the current timestep dealii::Vector<double> solution; /// The solution to the advection equation at the previous timestep dealii::Vector<double> old_solution; dealii::Vector<double> rhs; /// The length of each timestep const double timeStep = 1.0/3.0; /// The current time double currTime; /// The current timestep unsigned int step = 0; /// The final time const double finalTime = 1.0; }; template<unsigned int dim> AdvectionProblem<dim>::AdvectionProblem() : mapping(), fe(1), dofHandler(triangulation), currTime(timeStep) { // initialize a square grid and refine global InitializeGrid(5); // set up the system on this initial grid SetupSystem(); // reset the old solution old_solution.reinit(dofHandler.n_dofs()); } template<unsigned int dim> void AdvectionProblem<dim>::SetupSystem() { // distribute the dofs dofHandler.distribute_dofs(fe); // generate a sparsity pattern DynamicSparsityPattern dsp(dofHandler.n_dofs()); DoFTools::make_flux_sparsity_pattern(dofHandler, dsp); sparsityPattern.copy_from(dsp); // set up the strucutre of the components systemMatrix.reinit(sparsityPattern); solution.reinit(dofHandler.n_dofs()); rhs.reinit(dofHandler.n_dofs()); constraints.close(); } template<unsigned int dim> void AdvectionProblem<dim>::SetInitialCondition(Vector<double>& vec) { VectorTools::project(dofHandler, constraints, QGauss<dim>(fe.degree+1), InitialConditionMass<dim>(), vec); } template<unsigned int dim> void AdvectionProblem<dim>::AssembleSystem() { // an object that knows about data structures and local integration MeshWorker::IntegrationInfoBox<dim> infoBox; // initialize the quadrature formula const unsigned int nGauss = dofHandler.get_fe().degree + 1; infoBox.initialize_gauss_quadrature(nGauss, nGauss, nGauss); // these are the values we need to integrate our system infoBox.initialize_update_flags(); const UpdateFlags updateFlags = update_quadrature_points | update_values | update_gradients | update_JxW_values; infoBox.add_update_flags(updateFlags, true, true, true, true); // initialize the finite element values infoBox.initialize(fe, mapping); // create an object that forwards local data to the assembler MeshWorker::DoFInfo<dim> dofInfo(dofHandler); // create the assembler---tell it where to put local data MeshWorker::Assembler::SystemSimple<SparseMatrix<double>, Vector<double> > assembler; assembler.initialize(systemMatrix, rhs); IntegrateCell<dim> cellIntegration(old_solution); MeshWorker::loop<dim, dim, MeshWorker::DoFInfo<dim>, MeshWorker::IntegrationInfoBox<dim> >(dofHandler.begin_active(), dofHandler.end(), dofInfo, infoBox, cellIntegration, nullptr, nullptr, assembler); } template<unsigned int dim> void AdvectionProblem<dim>::InitializeGrid(unsigned int const nrefine) { GridGenerator::hyper_cube(triangulation); triangulation.refine_global(nrefine); } template<unsigned int dim> void AdvectionProblem<dim>::Run() { // project the initial conditions---on whatever grid is currently setup (constructor initializes something) SetInitialCondition(old_solution); // loop through time for( ; currTime<finalTime+timeStep/2.0; currTime+=timeStep, ++step ) { std::cout << "time: " << currTime << " of " << finalTime << std::endl; // set up the sparsity pattern for the system and reinit the solution SetupSystem(); solution = old_solution; // assemble the system AssembleSystem(); } } int main(int argc, char **argv) { AdvectionProblem<2> dgmethod; dgmethod.Run(); }