598 *
return -Utilities::fixed_power<2, double>(this->
get_time()) + 6;
618 *
const unsigned int component = 0)
const override;
636 *
const unsigned int component)
const
639 *
return -Utilities::fixed_power<2, double>(p(component)) -
640 *
Utilities::fixed_power<2, double>(this->
get_time()) + 6;
661 *
const unsigned int component = 0)
const override;
679 *
const unsigned int component)
const
684 *
2 *
interest_rate * Utilities::fixed_power<2, double>(p(component)) -
686 *
(-Utilities::fixed_power<2, double>(p(component)) -
687 *
Utilities::fixed_power<2, double>(this->
get_time()) + 6);
700 * <a name=
"ThecodeBlackScholescodeClass"></a>
755 *
void refine_grid();
785 *
const double theta;
786 *
const unsigned int n_cycles;
798 * <a name=
"ThecodeBlackScholescodeImplementation"></a>
832 * <a name=
"codeBlackScholessetup_systemcode"></a>
852 *
dof_handler.distribute_dofs(fe);
856 *
constraints.clear();
858 *
constraints.close();
864 *
sparsity_pattern.copy_from(
dsp);
870 *
system_matrix.
reinit(sparsity_pattern);
884 *
const unsigned int dofs_per_cell = fe.dofs_per_cell;
891 *
std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
892 *
for (
const auto &cell : dof_handler.active_cell_iterators())
896 *
for (
const unsigned int q_index : fe_values.quadrature_point_indices())
899 *
fe_values.quadrature_point(q_index).square();
900 *
for (
const unsigned int i : fe_values.dof_indices())
905 *
fe_values.shape_grad(i, q_index) *
906 *
fe_values.shape_grad(
j, q_index) *
907 *
fe_values.JxW(q_index));
910 *
cell->get_dof_indices(local_dof_indices);
911 *
for (
const unsigned int i : fe_values.dof_indices())
915 *
local_dof_indices[
j],
927 *
for (
const auto &cell : dof_handler.active_cell_iterators())
931 *
for (
const unsigned int q_index : fe_values.quadrature_point_indices())
934 *
fe_values.quadrature_point(q_index);
935 *
for (
const unsigned int i : fe_values.dof_indices())
941 *
fe_values.shape_grad(i, q_index) *
942 *
fe_values.shape_value(
j, q_index) *
943 *
fe_values.JxW(q_index));
947 *
cell->get_dof_indices(local_dof_indices);
948 *
for (
const unsigned int i : fe_values.dof_indices())
951 *
a_matrix.add(local_dof_indices[i],
952 *
local_dof_indices[
j],
964 *
for (
const auto &cell : dof_handler.active_cell_iterators())
968 *
for (
const unsigned int q_index : fe_values.quadrature_point_indices())
971 *
fe_values.quadrature_point(q_index);
972 *
for (
const unsigned int i : fe_values.dof_indices())
977 *
fe_values.shape_value(i, q_index) *
978 *
fe_values.shape_grad(
j, q_index) *
979 *
fe_values.JxW(q_index));
982 *
cell->get_dof_indices(local_dof_indices);
983 *
for (
const unsigned int i : fe_values.dof_indices())
986 *
b_matrix.add(local_dof_indices[i],
987 *
local_dof_indices[
j],
992 *
solution.
reinit(dof_handler.n_dofs());
999 * <a name=
"codeBlackScholessolve_time_stepcode"></a>
1010 *
template <
int dim>
1016 *
preconditioner.initialize(system_matrix, 1.0);
1017 *
cg.solve(system_matrix, solution,
system_rhs, preconditioner);
1018 *
constraints.distribute(solution);
1024 * <a name=
"codeBlackScholesadd_results_for_outputcode"></a>
1035 * template <int dim>
1036 * void BlackScholes<dim>::add_results_for_output()
1038 * data_out_stack.new_parameter_value(time, time_step);
1039 * data_out_stack.attach_dof_handler(dof_handler);
1040 * data_out_stack.add_data_vector(solution, solution_names);
1041 * data_out_stack.build_patches(2);
1042 * data_out_stack.finish_parameter_value();
1048 * <a name="codeBlackScholesrefine_gridcode"></a>
1049 * <h4><code>BlackScholes::refine_grid</code></h4>
1053 * It is somewhat unnecessary to have a function for the global refinement
1054 * that we do. The reason for the function is to allow for the possibility of
1055 * an adaptive refinement later.
1058 * template <int dim>
1059 * void BlackScholes<dim>::refine_grid()
1061 * triangulation.refine_global(1);
1067 * <a name="codeBlackScholesprocess_solutioncode"></a>
1068 * <h4><code>BlackScholes::process_solution</code></h4>
1072 * This is where we calculate the convergence and error data to evaluate the
1073 * effectiveness of the program. Here, we calculate the @f$L^2@f$, @f$H^1@f$ and
1074 * @f$L^{\infty}@f$ norms.
1077 * template <int dim>
1078 * void BlackScholes<dim>::process_solution()
1080 * Solution<dim> sol(maturity_time);
1081 * sol.set_time(time);
1082 * Vector<float> difference_per_cell(triangulation.n_active_cells());
1083 * VectorTools::integrate_difference(dof_handler,
1086 * difference_per_cell,
1087 * QGauss<dim>(fe.degree + 1),
1088 * VectorTools::L2_norm);
1089 * const double L2_error =
1090 * VectorTools::compute_global_error(triangulation,
1091 * difference_per_cell,
1092 * VectorTools::L2_norm);
1093 * VectorTools::integrate_difference(dof_handler,
1096 * difference_per_cell,
1097 * QGauss<dim>(fe.degree + 1),
1098 * VectorTools::H1_seminorm);
1099 * const double H1_error =
1100 * VectorTools::compute_global_error(triangulation,
1101 * difference_per_cell,
1102 * VectorTools::H1_seminorm);
1103 * const QTrapezoid<1> q_trapezoid;
1104 * const QIterated<dim> q_iterated(q_trapezoid, fe.degree * 2 + 1);
1105 * VectorTools::integrate_difference(dof_handler,
1108 * difference_per_cell,
1110 * VectorTools::Linfty_norm);
1111 * const double Linfty_error =
1112 * VectorTools::compute_global_error(triangulation,
1113 * difference_per_cell,
1114 * VectorTools::Linfty_norm);
1115 * const unsigned int n_active_cells = triangulation.n_active_cells();
1116 * const unsigned int n_dofs = dof_handler.n_dofs();
1117 * convergence_table.add_value("cells", n_active_cells);
1118 * convergence_table.add_value("dofs", n_dofs);
1119 * convergence_table.add_value("L2", L2_error);
1120 * convergence_table.add_value("H1", H1_error);
1121 * convergence_table.add_value("Linfty", Linfty_error);
1127 * <a name="codeBlackScholeswrite_convergence_tablecode"></a>
1128 * <h4><code>BlackScholes::write_convergence_table</code> </h4>
1132 * This next part is building the convergence and error tables. By this, we
1133 * need to set the settings for how to output the data that was calculated
1134 * during <code>BlackScholes::process_solution</code>. First, we will create
1135 * the headings and set up the cells properly. During this, we will also
1136 * prescribe the precision of our results. Then we will write the calculated
1137 * errors based on the @f$L^2@f$, @f$H^1@f$, and @f$L^{\infty}@f$ norms to the console and
1138 * to the error LaTeX file.
1141 * template <int dim>
1142 * void BlackScholes<dim>::write_convergence_table()
1144 * convergence_table.set_precision("L2", 3);
1145 * convergence_table.set_precision("H1", 3);
1146 * convergence_table.set_precision("Linfty", 3);
1147 * convergence_table.set_scientific("L2", true);
1148 * convergence_table.set_scientific("H1", true);
1149 * convergence_table.set_scientific("Linfty", true);
1150 * convergence_table.set_tex_caption("cells", "\\# cells");
1151 * convergence_table.set_tex_caption("dofs", "\\# dofs");
1152 * convergence_table.set_tex_caption("L2", "@fL^2@f-error");
1153 * convergence_table.set_tex_caption("H1", "@fH^1@f-error");
1154 * convergence_table.set_tex_caption("Linfty", "@fL^\\infty@f-error");
1155 * convergence_table.set_tex_format("cells", "r");
1156 * convergence_table.set_tex_format("dofs", "r");
1157 * std::cout << std::endl;
1158 * convergence_table.write_text(std::cout);
1159 * std::string error_filename = "error";
1160 * error_filename += "-global";
1161 * error_filename += ".tex";
1162 * std::ofstream error_table_file(error_filename);
1163 * convergence_table.write_tex(error_table_file);
1167 * Next, we will make the convergence table. We will again write this to
1168 * the console and to the convergence LaTeX file.
1171 * convergence_table.add_column_to_supercolumn("cells", "n cells");
1172 * std::vector<std::string> new_order;
1173 * new_order.emplace_back("n cells");
1174 * new_order.emplace_back("H1");
1175 * new_order.emplace_back("L2");
1176 * convergence_table.set_column_order(new_order);
1177 * convergence_table.evaluate_convergence_rates(
1178 * "L2", ConvergenceTable::reduction_rate);
1179 * convergence_table.evaluate_convergence_rates(
1180 * "L2", ConvergenceTable::reduction_rate_log2);
1181 * convergence_table.evaluate_convergence_rates(
1182 * "H1", ConvergenceTable::reduction_rate);
1183 * convergence_table.evaluate_convergence_rates(
1184 * "H1", ConvergenceTable::reduction_rate_log2);
1185 * std::cout << std::endl;
1186 * convergence_table.write_text(std::cout);
1187 * std::string conv_filename = "convergence";
1188 * conv_filename += "-global";
1189 * switch (fe.degree)
1192 * conv_filename += "-q1";
1195 * conv_filename += "-q2";
1198 * Assert(false, ExcNotImplemented());
1200 * conv_filename += ".tex";
1201 * std::ofstream table_file(conv_filename);
1202 * convergence_table.write_tex(table_file);
1208 * <a name="codeBlackScholesruncode"></a>
1209 * <h4><code>BlackScholes::run</code></h4>
1213 * Now we get to the main driver of the program. This is where we do all the
1214 * work of looping through the time steps and calculating the solution vector
1215 * each time. Here at the top, we set the initial refinement value and then
1216 * create a mesh. Then we refine this mesh once. Next, we set up the
1217 * data_out_stack object to store our solution. Finally, we start a for loop
1218 * to loop through the cycles. This lets us recalculate a solution for each
1219 * successive mesh refinement. At the beginning of each iteration, we need to
1220 * reset the time and time step number. We introduce an if statement to
1224 *
template <
int dim>
1237 *
for (
unsigned int cycle = 0; cycle < n_cycles; ++cycle)
1247 *
std::cout << std::endl
1248 *
<<
"===========================================" << std::endl
1249 *
<<
"Cycle " << cycle <<
':' << std::endl
1250 *
<<
"Number of active cells: "
1252 *
<<
"Number of degrees of freedom: " << dof_handler.n_dofs()
1260 *
if (cycle == (n_cycles - 1))
1346 *
system_matrix.copy_from(mass_matrix);
1347 *
system_matrix.add(
1354 *
constraints.condense(system_matrix,
system_rhs);
1395 *
if (cycle == (n_cycles - 1))
1405 *
const std::string
filename =
"solution.vtk";
1419 * <a name=
"ThecodemaincodeFunction"></a>
1437 *
catch (std::exception &exc)
1439 *
std::cerr << std::endl
1441 *
<<
"----------------------------------------------------"
1443 *
std::cerr <<
"Exception on processing: " << std::endl
1444 *
<< exc.what() << std::endl
1445 *
<<
"Aborting!" << std::endl
1446 *
<<
"----------------------------------------------------"
1452 *
std::cerr << std::endl
1454 *
<<
"----------------------------------------------------"
1456 *
std::cerr <<
"Unknown exception!" << std::endl
1457 *
<<
"Aborting!" << std::endl
1458 *
<<
"----------------------------------------------------"
1471===========================================
1475Time step 0 at t=0.0002
1482Time step 0 at t=0.0002
1483Time step 1000 at t=0.2002
1484Time step 2000 at t=0.4002
1485Time step 3000 at t=0.6002
1486Time step 4000 at t=0.8002
1489 1 2 1.667e-01 5.774e-01 2.222e-01
1490 2 3 3.906e-02 2.889e-01 5.380e-02
1491 4 5 9.679e-03 1.444e-01 1.357e-02
1492 8 9 2.405e-03 7.218e-02 3.419e-03
1493 16 17 5.967e-04 3.609e-02 8.597e-04
1494 32 33 1.457e-04 1.804e-02 2.155e-04
1495 64 65 3.307e-05 9.022e-03 5.388e-05
1496 128 129 5.016e-06 4.511e-03 1.342e-05
1499 1 5.774e-01 - - 1.667e-01 - -
1500 2 2.889e-01 2.00 1.00 3.906e-02 4.27 2.09
1501 4 1.444e-01 2.00 1.00 9.679e-03 4.04 2.01
1502 8 7.218e-02 2.00 1.00 2.405e-03 4.02 2.01
1503 16 3.609e-02 2.00 1.00 5.967e-04 4.03 2.01
1504 32 1.804e-02 2.00 1.00 1.457e-04 4.10 2.03
1505 64 9.022e-03 2.00 1.00 3.307e-05 4.41 2.14
1506 128 4.511e-03 2.00 1.00 5.016e-06 6.59 2.72
1519 <
img src=
"https://www.dealii.org/images/steps/developer/step-78.mms-solution.png"
1520 alt=
"Solution of the MMS problem.">
1524<a name=
"PlainProg"></a>
value_type * data() const noexcept
void reinit(value_type *starting_element, const std::size_t n_elements)
__global__ void set(Number *val, const Number s, const size_type N)
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
void loop(ITERATOR begin, std_cxx20::type_identity_t< ITERATOR > end, DOFINFO &dinfo, INFOBOX &info, const std::function< void(DOFINFO &, typename INFOBOX::CellInfo &)> &cell_worker, const std::function< void(DOFINFO &, typename INFOBOX::CellInfo &)> &boundary_worker, const std::function< void(DOFINFO &, DOFINFO &, typename INFOBOX::CellInfo &, typename INFOBOX::CellInfo &)> &face_worker, ASSEMBLER &assembler, const LoopControl &lctrl=LoopControl())
void make_hanging_node_constraints(const DoFHandler< dim, spacedim > &dof_handler, AffineConstraints< number > &constraints)
void make_sparsity_pattern(const DoFHandler< dim, spacedim > &dof_handler, SparsityPatternBase &sparsity_pattern, const AffineConstraints< number > &constraints=AffineConstraints< number >(), const bool keep_constrained_dofs=true, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id)
@ update_values
Shape function values.
@ update_JxW_values
Transformed quadrature weights.
@ update_gradients
Shape function gradients.
@ update_quadrature_points
Transformed quadrature points.
void hyper_cube(Triangulation< dim, spacedim > &tria, const double left=0., const double right=1., const bool colorize=false)
void refine(Triangulation< dim, spacedim > &tria, const Vector< Number > &criteria, const double threshold, const unsigned int max_to_mark=numbers::invalid_unsigned_int)
@ matrix
Contents is actually a matrix.
@ symmetric
Matrix is symmetric.
void cell_matrix(FullMatrix< double > &M, const FEValuesBase< dim > &fe, const FEValuesBase< dim > &fetest, const ArrayView< const std::vector< double > > &velocity, const double factor=1.)
double norm(const FEValuesBase< dim > &fe, const ArrayView< const std::vector< Tensor< 1, dim > > > &Du)
void L2(Vector< number > &result, const FEValuesBase< dim > &fe, const std::vector< double > &input, const double factor=1.)
void mass_matrix(FullMatrix< double > &M, const FEValuesBase< dim > &fe, const double factor=1.)
void create_mass_matrix(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof, const Quadrature< dim > &q, SparseMatrixType &matrix, const Function< spacedim, typename SparseMatrixType::value_type > *const a=nullptr, const AffineConstraints< typename SparseMatrixType::value_type > &constraints=AffineConstraints< typename SparseMatrixType::value_type >())
Tensor< 2, dim, Number > F(const Tensor< 2, dim, Number > &Grad_u)
void run(const Iterator &begin, const std_cxx20::type_identity_t< Iterator > &end, Worker worker, Copier copier, const ScratchData &sample_scratch_data, const CopyData &sample_copy_data, const unsigned int queue_length, const unsigned int chunk_size)
int(&) functions(const void *v1, const void *v2)
::VectorizedArray< Number, width > exp(const ::VectorizedArray< Number, width > &)
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > invert(const SymmetricTensor< 2, dim, Number > &)