void EigenvalueProblem<dim>::output_results() const { DataOut<dim> data_out; data_out.attach_dof_handler(dof_handler); for (size_t i = 0; i < eigenfunctions.size(); ++i) { data_out.add_data_vector(eigenfunctions[i], std::string("eigenfunction_") + Utilities::int_to_string(i)); } Vector<double> projected_potential (dof_handler.n_dofs()); { FunctionParser<dim> potential; potential.initialize (FunctionParser<dim>::default_variable_names (), parameters.get ("Potential"), typename FunctionParser<dim>::ConstMap()); VectorTools::interpolate (dof_handler, potential, projected_potential); } data_out.add_data_vector (projected_potential, "interpolated_potential"); data_out.build_patches (); std::ofstream output ("eigenvectors.vtk"); data_out.write_vtk (output); }
void EigenvalueProblem<dim>::assemble_system() { QGauss<dim> quadrature_formula(2); FEValues<dim> fe_values(fe, quadrature_formula, update_values | update_gradients | update_quadrature_points | update_JxW_values); const size_t dofs_per_cell = fe.dofs_per_cell; const size_t n_q_points = quadrature_formula.size(); FullMatrix<double> cell_stiffness_matrix (dofs_per_cell, dofs_per_cell); FullMatrix<double> cell_mass_matrix (dofs_per_cell, dofs_per_cell); std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell); FunctionParser<dim> potential; potential.initialize(FunctionParser<dim>::default_variable_names(), parameters.get("Potential"), typename FunctionParser<dim>::ConstMap()); std::vector<double> potential_values(n_q_points); for (auto cell : dof_handler.active_cell_iterators()) { fe_values.reinit(cell); cell_stiffness_matrix = 0; cell_mass_matrix = 0; potential.value_list(fe_values.get_quadrature_points(), potential_values); for (size_t q_point = 0; q_point < n_q_points; ++q_point) { for (size_t i = 0; i < dofs_per_cell; ++i) { for (size_t j = 0; j < dofs_per_cell; ++j) { cell_stiffness_matrix(i, j) += (fe_values.shape_grad(i, q_point) * fe_values.shape_grad(j, q_point) + potential_values[q_point] * fe_values.shape_value(i, q_point) * fe_values.shape_value(j, q_point) ) * fe_values.JxW(q_point); cell_mass_matrix(i, j) += (fe_values.shape_value(i, q_point) * fe_values.shape_value(j, q_point) ) * fe_values.JxW(q_point); } } } cell->get_dof_indices(local_dof_indices); constraints.distribute_local_to_global(cell_stiffness_matrix, local_dof_indices, stiffness_matrix); constraints.distribute_local_to_global(cell_mass_matrix, local_dof_indices, mass_matrix); } stiffness_matrix.compress(VectorOperation::add); mass_matrix.compress(VectorOperation::add); double min_spurious_eigenvalue = std::numeric_limits<double>::max(), max_spurious_eigenvalue = -std::numeric_limits<double>::max(); for (size_t i = 0; i < dof_handler.n_dofs(); ++i) { if (constraints.is_constrained(i)) { const double ev = stiffness_matrix(i, i) / mass_matrix(i, i); min_spurious_eigenvalue = std::min (min_spurious_eigenvalue, ev); max_spurious_eigenvalue = std::max (max_spurious_eigenvalue, ev); } } std::cout << " Spurious eigenvalues are all in the interval " << "[" << min_spurious_eigenvalue << "," << max_spurious_eigenvalue << "]" << std::endl; }