334 * braid_StepStatusGetLevel(status, &
level);
335 * braid_StepStatusGetTstartTstop(status, &tstart, &tstop);
336 * braid_StepStatusGetTIndex(status, &index);
338 * deltaT = tstop - tstart;
340 * ::Vector<double>& solution = u->data;
342 * HeatEquation<2>& heateq = app->eq;
344 * heateq.step(solution, deltaT, tstart, index);
352 * In
this function we initialize a vector at an arbitrary time.
353 * At
this point we don
't know anything about what the solution
354 * looks like, and we can really initialize to anything, so in
355 * this case use reinit to initialize the memory and set the
360 * my_Init(braid_App app,
362 * braid_Vector *u_ptr)
364 * my_Vector *u = new(my_Vector);
365 * int size = app->eq.size();
366 * u->data.reinit(size);
368 * app->eq.initialize(t, u->data);
377 * Here we need to copy the vector u into the vector v. We do this
378 * by allocating a new vector, then reinitializing the deal.ii
379 * vector to the correct size. The deal.ii reinitialization sets
380 * every value to zero, so next we need to iterate over the vector
381 * u and copy the values to the new vector v.
385 * my_Clone(braid_App app,
387 * braid_Vector *v_ptr)
390 * my_Vector *v = new(my_Vector);
391 * int size = u->data.size();
392 * v->data.reinit(size);
393 * for(size_t i=0, end=v->data.size(); i != end; ++i)
395 * v->data[i] = u->data[i];
404 * Here we need to free the memory used by vector u. This is
405 * pretty simple since the deal.ii vector is stored inside the
406 * XBraid vector, so we just delete the XBraid vector u and it
407 * puts the deal.ii vector out of scope and releases its memory.
411 * my_Free(braid_App app,
422 * This is to perform an axpy type operation. That is to say we
423 * do @f$y = \alpha x + \beta y@f$. Fortunately deal.ii already has
424 * this operation built in to its vector class, so we get the
425 * reference to the vector y and call the sadd method.
428 * int my_Sum(braid_App app,
435 * Vector<double>& vec = y->data;
436 * vec.sadd(beta, alpha, x->data);
443 * This calculates the spatial norm using the l2 norm. According
444 * to XBraid, this could be just about any spatial norm but we'll
445 * keep it simple and used deal.ii vector
's built in l2_norm method.
449 * my_SpatialNorm(braid_App app,
455 * dot = u->data.l2_norm();
463 * This function is called at various points depending on the access
464 * level specified when configuring the XBraid struct. This function
465 * is used to print out data during the run time, such as plots of the
466 * data. The status struct contains a ton of information about the
467 * simulation run. Here we get the current time and timestep number.
468 * The output_results function is called to plot the solution data.
469 * If the method of manufactured solutions is being used, then the
470 * error of this time step is computed and processed.
474 * my_Access(braid_App app,
476 * braid_AccessStatus astatus)
481 * braid_AccessStatusGetT(astatus, &t);
482 * braid_AccessStatusGetTIndex(astatus, &index);
484 * app->eq.output_results(index, t, u->data);
487 * if(index == app->final_step)
489 * app->eq.process_solution(t, index, u->data);
498 * This calculates the size of buffer needed to pack the solution
499 * data into a linear buffer for transfer to another processor via
500 * MPI. We query the size of the data from the HeatEquation class
501 * and return the buffer size.
505 * my_BufSize(braid_App app,
507 * braid_BufferStatus bstatus)
510 * int size = app->eq.size();
511 * *size_ptr = (size+1)*sizeof(double);
518 * This function packs a linear buffer with data so that the buffer
519 * may be sent to another processor via MPI. The buffer is cast to
520 * a type we can work with. The first element of the buffer is the
521 * size of the buffer. Then we iterate over soltuion vector u and
522 * fill the buffer with our solution data. Finally we tell XBraid
523 * how much data we wrote.
527 * my_BufPack(braid_App app,
530 * braid_BufferStatus bstatus)
534 * double *dbuffer = (double*)buffer;
535 * int size = u->data.size();
537 * for(int i=0; i != size; ++i)
539 * dbuffer[i+1] = (u->data)[i];
541 * braid_BufferStatusSetSize(bstatus, (size+1)*sizeof(double));
548 * This function unpacks a buffer that was recieved from a different
549 * processor via MPI. The size of the buffer is read from the first
550 * element, then we iterate over the size of the buffer and fill
551 * the values of solution vector u with the data in the buffer.
555 * my_BufUnpack(braid_App app,
557 * braid_Vector *u_ptr,
558 * braid_BufferStatus bstatus)
563 * my_Vector *u = NULL;
564 * double *dbuffer = (double*)buffer;
565 * int size = static_cast<int>(dbuffer[0]);
566 * u = new(my_Vector);
567 * u->data.reinit(size);
569 * for(int i = 0; i != size; ++i)
571 * (u->data)[i] = dbuffer[i+1];
580<a name="ann-src/BraidFuncs.hh"></a>
581<h1>Annotated version of src/BraidFuncs.hh</h1>
587 * #ifndef _BRAIDFUNCS_H_
588 * #define _BRAIDFUNCS_H_
591 * * \file BraidFuncs.cc
592 * * \brief Contains the implementation of the mandatory X-Braid functions
594 * * X-Braid mandates several functions in order to drive the solution.
595 * * This file contains the implementation of said mandatory functions.
596 * * See the X-Braid documentation for more information.
597 * * There are several functions that are optional in X-Braid that may
598 * * or may not be implemented in here.
603 * /*-------- Third Party --------*/
604 * #include <deal.II/numerics/vector_tools.h>
607 * #include <braid_test.h>
609 * /*-------- Project --------*/
610 * #include "HeatEquation.hh"
614 * This struct contains all data that changes with time. For now
615 * this is just the solution data. When doing AMR this should
616 * probably include the triangulization, the sparsity patter,
621 * * \brief Struct that contains the deal.ii vector.
623 * typedef struct _braid_Vector_struct
625 * ::Vector<double> data;
630 * This struct contains all the data that is unchanging with time.
634 * * \brief Struct that contains the HeatEquation and final
635 * * time step number.
637 * typedef struct _braid_App_struct
639 * HeatEquation<2> eq;
645 * * @brief my_Step - Takes a step in time, advancing the u vector
647 * * @param app - The braid app struct
648 * * @param ustop - The solution data at the end of this time step
649 * * @param fstop - RHS data (such as forcing function?)
650 * * @param u - The solution data at the beginning of this time step
651 * * @param status - Status structure that contains various info of this time
653 * * @return Success (0) or failure (1)
655 * int my_Step(braid_App app,
656 * braid_Vector ustop,
657 * braid_Vector fstop,
659 * braid_StepStatus status);
663 * * @brief my_Init - Initializes a solution data at the given time
664 * * For now, initializes the solution to zero no matter what time we are at
666 * * @param app - The braid app struct containing user data
667 * * @param t - Time at which the solution is initialized
668 * * @param u_ptr - The solution data that needs to be filled
670 * * @return Success (0) or failure (1)
673 * my_Init(braid_App app,
675 * braid_Vector *u_ptr);
679 * * @brief my_Clone - Clones a vector into a new vector
681 * * @param app - The braid app struct containing user data
682 * * @param u - The existing vector containing data
683 * * @param v_ptr - The empty vector that needs to be filled
685 * * @return Success (0) or failure (1)
688 * my_Clone(braid_App app,
690 * braid_Vector *v_ptr);
694 * * @brief my_Free - Deletes a vector
696 * * @param app - The braid app struct containing user data
697 * * @param u - The vector that needs to be deleted
699 * * @return Success (0) or failure (1)
702 * my_Free(braid_App app,
707 * * @brief my_Sum - Sums two vectors in an AXPY operation
708 * * The operation is y = alpha*x + beta*y
710 * * @param app - The braid app struct containing user data
711 * * @param alpha - The coefficient in front of x
712 * * @param x - A vector that is multiplied by alpha then added to y
713 * * @param beta - The coefficient of y
714 * * @param y - A vector that is multiplied by beta then summed with x
716 * * @return Success (0) or failure (1)
719 * my_Sum(braid_App app,
726 * * \brief Returns the spatial norm of the provided vector
728 * * Calculates and returns the spatial norm of the provided vector.
729 * * Interestingly enough, X-Braid does not specify a particular norm.
730 * * to keep things simple, we implement the Euclidean norm.
732 * * \param app - The braid app struct containing user data
733 * * \param u - The vector we need to take the norm of
734 * * \param norm_ptr - Pointer to the norm that was calculated, need to modify this
735 * * \return Success (0) or failure (1)
738 * my_SpatialNorm(braid_App app,
743 * * \brief Allows the user to output details
745 * * The Access function is called at various points to allow the user to output
746 * * information to the screen or to files.
747 * * The astatus parameter provides various information about the simulation,
748 * * see the XBraid documentation for details on what information you can get.
749 * * Example information is what the current timestep number and current time is.
750 * * If the access level (in parallel_in_time.cc) is set to 0, this function is
752 * * If the access level is set to 1, the function is called after the last
754 * * If the access level is set to 2, it is called every XBraid cycle.
756 * * \param app - The braid app struct containing user data
757 * * \param u - The vector containing the data at the status provided
758 * * \param astatus - The Braid status structure
759 * * \return Success (0) or failure (1)
762 * my_Access(braid_App app,
764 * braid_AccessStatus astatus);
767 * * \brief Calculates the size of a buffer for MPI data transfer
769 * * Calculates the size of the buffer that is needed to transfer
770 * * a solution vector to another processor.
771 * * The bstatus parameter provides various information on the
772 * * simulation, see the XBraid documentation for all possible
775 * * \param app - The braid app struct containing user data
776 * * \param size_ptr A pointer to the calculated size
777 * * \param bstatus The XBraid status structure
778 * * \return Success (0) or failure (1)
781 * my_BufSize(braid_App app,
783 * braid_BufferStatus bstatus);
786 * * \brief Linearizes a vector to be sent to another processor
788 * * Linearizes (packs) a data buffer with the contents of
789 * * some solution state u.
791 * * \param app - The braid app struct containing user data
792 * * \param u The vector that must be packed into buffer
793 * * \param buffer The buffer that must be filled with u
794 * * \param bstatus The XBraid status structure
795 * * \return Success (0) or failure (1)
798 * my_BufPack(braid_App app,
801 * braid_BufferStatus bstatus);
804 * * \brief Unpacks a vector that was sent from another processor
806 * * Unpacks a linear data buffer into the vector pointed to by
809 * * \param app - The braid app struct containing user data
810 * * \param buffer The buffer that must be unpacked
811 * * \param u_ptr The pointer to the vector that is filled
812 * * \param bstatus The XBraid status structure
813 * * \return Success (0) or failure (1)
816 * my_BufUnpack(braid_App app,
818 * braid_Vector *u_ptr,
819 * braid_BufferStatus bstatus);
821 * #endif // _BRAIDFUNCS_H_
825<a name="ann-src/HeatEquation.hh"></a>
826<h1>Annotated version of src/HeatEquation.hh</h1>
832 * #ifndef _HEATEQUATION_H_
833 * #define _HEATEQUATION_H_
835 * #include <deal.II/base/utilities.h>
836 * #include <deal.II/base/quadrature_lib.h>
837 * #include <deal.II/base/function.h>
838 * #include <deal.II/base/logstream.h>
839 * #include <deal.II/lac/vector.h>
840 * #include <deal.II/lac/full_matrix.h>
841 * #include <deal.II/lac/dynamic_sparsity_pattern.h>
842 * #include <deal.II/lac/sparse_matrix.h>
843 * #include <deal.II/lac/solver_cg.h>
844 * #include <deal.II/lac/precondition.h>
845 * #include <deal.II/lac/affine_constraints.h>
846 * #include <deal.II/grid/tria.h>
847 * #include <deal.II/grid/grid_generator.h>
848 * #include <deal.II/grid/grid_refinement.h>
849 * #include <deal.II/grid/grid_out.h>
850 * #include <deal.II/grid/tria_accessor.h>
851 * #include <deal.II/grid/tria_iterator.h>
852 * #include <deal.II/dofs/dof_handler.h>
853 * #include <deal.II/dofs/dof_accessor.h>
854 * #include <deal.II/dofs/dof_tools.h>
855 * #include <deal.II/fe/fe_q.h>
856 * #include <deal.II/fe/fe_values.h>
857 * #include <deal.II/numerics/data_out.h>
858 * #include <deal.II/numerics/vector_tools.h>
859 * #include <deal.II/numerics/error_estimator.h>
860 * #include <deal.II/numerics/solution_transfer.h>
861 * #include <deal.II/numerics/matrix_tools.h>
862 * #include <deal.II/base/convergence_table.h>
866 * using namespace dealii;
870 * The HeatEquation class is describes the finite element
871 * solver for the heat equation. It contains all the functions
872 * needed to define the problem domain and advance the solution
882 * void step(Vector<double>& braid_data,
887 * int size() const; /// Returns the size of the solution vector
889 * void output_results(int a_time_idx,
891 * Vector<double>& a_solution) const;
893 * void initialize(double a_time,
894 * Vector<double>& a_vector) const;
896 * void process_solution(double a_time,
898 * const Vector<double>& a_vector);
901 * void setup_system();
902 * void solve_time_step(Vector<double>& a_solution);
904 * Triangulation<dim> triangulation;
906 * DoFHandler<dim> dof_handler;
908 * AffineConstraints<double> constraints;
910 * SparsityPattern sparsity_pattern;
911 * SparseMatrix<double> mass_matrix;
912 * SparseMatrix<double> laplace_matrix;
913 * SparseMatrix<double> system_matrix;
915 * Vector<double> system_rhs;
917 * std::ofstream myfile;
919 * const double theta;
923 * These were originally in the run() function but because
924 * I am splitting the run() function up into define and step
925 * they need to become member data
928 * Vector<double> tmp;
929 * Vector<double> forcing_terms;
931 * ConvergenceTable convergence_table;
936 * The RightHandSide class describes the RHS of the governing
937 * equations. In this case, it is the forcing function.
941 * class RightHandSide : public Function<dim>
950 * virtual double value (const Point<dim> &p,
951 * const unsigned int component = 0) const override;
954 * const double period;
959 * The BoundaryValues class describes the boundary conditions
960 * of the governing equations.
964 * class BoundaryValues : public Function<dim>
967 * virtual double value (const Point<dim> &p,
968 * const unsigned int component = 0) const override;
973 * The RightHandSideMFG class describes the right hand side
974 * function when doing the method of manufactured solutions.
978 * class RightHandSideMFG : public Function<dim>
981 * virtual double value (const Point<dim> &p,
982 * const unsigned int component = 0) const override;
987 * The InitialValuesMFG class describes the initial values
988 * when doing the method of manufactured solutions.
992 * class InitialValuesMFG : public Function<dim>
995 * virtual double value (const Point<dim> &p,
996 * const unsigned int component = 0) const override;
1001 * Provides the exact value for the manufactured solution. This
1002 * is used for the boundary conditions as well.
1005 * template <int dim>
1006 * class ExactValuesMFG : public Function<dim>
1010 * * \brief Computes the value at the given point and member data time
1012 * * Computes the exact value of the manufactured solution at point p and
1013 * * the member data time. See the class documentation and the design doc
1014 * * for details on what the exact solution is.
1016 * * \param p The point that the exact solution is computed at
1017 * * \param component The component of the exact solution (always 0 for now)
1018 * * \return double The exact value that was computed
1020 * virtual double value (const Point<dim> &p,
1021 * const unsigned int component = 0) const override;
1024 * * \brief Computes the gradient of the exact solution at the given point
1026 * * Computes the gradient of the exact/manufactured solution value at
1027 * * point p and member data time. See the design doc for details on
1028 * * what the gradient of the exact solution is
1030 * * \param p The point that the gradient is calculated at
1031 * * \param component The component of the system of equations this gradient is for
1032 * * \return Tensor<1,dim> A rank 1 tensor that contains the gradient
1033 * * in each spatial dimension
1035 * virtual Tensor<1,dim> gradient (const Point<dim> &p,
1036 * const unsigned int component = 0) const override;
1040 * #include "HeatEquationImplem.hh"
1042 * #endif // _HEATEQUATION_H_
1046<a name="ann-src/HeatEquationImplem.hh"></a>
1047<h1>Annotated version of src/HeatEquationImplem.hh</h1>
1053 * #include "Utilities.hh"
1055 * #include <iomanip>
1060 * Calculates the forcing function for the RightHandSide. See the
1061 * documentation for the math.
1064 * template <int dim>
1065 * double RightHandSide<dim>::value (const Point<dim> &p,
1066 * const unsigned int component) const
1069 * Assert (component == 0, ExcIndexRange(component, 0, 1));
1070 * Assert (dim == 2, ExcNotImplemented());
1072 * double time = this->get_time();
1074 * if ((p[0] > 0.5) && (p[1] > -0.5))
1076 * return std::exp(-0.5*(time-0.125)*(time-0.125)/(0.005));
1078 * else if ((p[0] > -0.5) && (p[1] > 0.5))
1080 * return std::exp(-0.5*(time-0.375)*(time-0.375)/(0.005));
1087 * return 0; // No forcing function
1092 * Calculates the forcing function for the method of manufactured
1093 * solutions. See the documentation for the math.
1096 * template <int dim>
1097 * double RightHandSideMFG<dim>::value (const Point<dim> &p,
1098 * const unsigned int component) const
1101 * Assert (component == 0, ExcIndexRange(component, 0, 1));
1102 * Assert (dim == 2, ExcNotImplemented());
1104 * double time = this->get_time();
1106 * double pi = numbers::PI;
1107 * return 4*pi*pi*std::exp(-4*pi*pi*time)*std::cos(2*pi*p[0])*std::cos(2*pi*p[1]);
1112 * Calculates the boundary conditions, essentially zero everywhere.
1115 * template <int dim>
1116 * double BoundaryValues<dim>::value (const Point<dim> &p,
1117 * const unsigned int component) const
1121 * Assert (component == 0, ExcIndexRange(component, 0, 1));
1127 * Calculates the exact solution (and thus also boundary conditions)
1128 * for the method of manufactured solutions.
1131 * template <int dim>
1132 * double ExactValuesMFG<dim>::value (const Point<dim> &p,
1133 * const unsigned int component) const
1136 * Assert (component == 0, ExcIndexRange(component, 0, 1));
1138 * double time = this->get_time();
1139 * const double pi = numbers::PI;
1141 * return std::exp(-4*pi*pi*time)*std::cos(2*pi*p[0])*std::cos(2*pi*p[1]);
1146 * Calculates the gradient of the exact solution for the method of manufactured
1147 * solutions. See the documentation for the math.
1150 * template <int dim>
1151 * Tensor<1,dim> ExactValuesMFG<dim>::gradient (const Point<dim> &p,
1152 * const unsigned int) const
1154 * Assert (dim == 2, ExcNotImplemented());
1156 * Tensor<1,dim> return_value;
1157 * const double pi = numbers::PI;
1158 * double time = this->get_time();
1159 * return_value[0] = -2*pi*std::exp(-4*pi*pi*time)*std::cos(2*pi*p[1])*std::sin(2*pi*p[0]);
1160 * return_value[1] = -2*pi*std::exp(-4*pi*pi*time)*std::cos(2*pi*p[0])*std::sin(2*pi*p[1]);
1161 * return return_value;
1166 * Calculates the initial values for the method of manufactured solutions.
1167 * See the documentation for the math.
1170 * template <int dim>
1171 * double InitialValuesMFG<dim>::value (const Point<dim> &p,
1172 * const unsigned int component) const
1175 * Assert (component == 0, ExcIndexRange(component, 0, 1));
1176 * const double pi = numbers::PI;
1178 * return std::cos(2*pi*p[0])*std::cos(2*pi*p[1]);
1181 * template <int dim>
1182 * HeatEquation<dim>::HeatEquation ()
1185 * dof_handler(triangulation),
1190 * template <int dim>
1191 * void HeatEquation<dim>::initialize(double a_time,
1192 * Vector<double>& a_vector) const
1197 * We only initialize values in the manufactured solution case
1200 * InitialValuesMFG<dim> iv_function;
1201 * iv_function.set_time(a_time);
1202 * VectorTools::project (dof_handler, constraints,
1203 * QGauss<dim>(fe.degree+1), iv_function,
1211 * If not the MFG solution case, a_vector is already zero'd so
do nothing
1216 *
template <
int dim>
1217 *
void HeatEquation<dim>::setup_system()
1219 * dof_handler.distribute_dofs(fe);
1221 * constraints.clear ();
1224 * constraints.close();
1231 * sparsity_pattern.copy_from(dsp);
1234 * laplace_matrix.reinit(sparsity_pattern);
1235 * system_matrix.reinit(sparsity_pattern);
1244 * system_rhs.reinit(dof_handler.n_dofs());
1248 *
template <
int dim>
1249 *
void HeatEquation<dim>::solve_time_step(
Vector<double>& a_solution)
1251 *
SolverControl solver_control(1000, 1e-8 * system_rhs.l2_norm());
1255 * preconditioner.
initialize(system_matrix, 1.0);
1257 * cg.solve(system_matrix, a_solution, system_rhs,
1260 * constraints.distribute(a_solution);
1265 *
template <
int dim>
1266 *
void HeatEquation<dim>::output_results(
int a_time_idx,
1272 * vtk_flags.
time = a_time;
1273 * vtk_flags.cycle = a_time_idx;
1278 * data_out.attach_dof_handler(dof_handler);
1279 * data_out.add_data_vector(a_solution,
"U");
1281 * data_out.build_patches();
1283 *
const std::string filename =
"solution-"
1286 * std::ofstream output(filename.c_str());
1287 * data_out.write_vtk(output);
1292 * We define the geometry here,
this is called on each processor
1293 * and doesn
't change in time. Once doing AMR, this won't need
1297 *
template <
int dim>
1298 *
void HeatEquation<dim>::define()
1300 *
const unsigned int initial_global_refinement = 6;
1307 * tmp.reinit (dof_handler.n_dofs());
1308 * forcing_terms.reinit (dof_handler.n_dofs());
1313 * Here we
advance the solution forward in time. This is done
1314 * the same way as in the
loop in @ref step_26
"step-26"'s run function.
1318 * void HeatEquation<dim>::step(Vector<double>& braid_data,
1326 * mass_matrix.vmult(system_rhs, braid_data);
1328 * laplace_matrix.vmult(tmp, braid_data);
1330 * system_rhs.add(-(1 - theta) * deltaT, tmp);
1333 * RightHandSideMFG<dim> rhs_function;
1335 * RightHandSide<dim> rhs_function;
1337 * rhs_function.set_time(a_time);
1338 * VectorTools::create_right_hand_side(dof_handler,
1339 * QGauss<dim>(fe.degree+1),
1343 * forcing_terms = tmp;
1344 * forcing_terms *= deltaT * theta;
1346 * rhs_function.set_time(a_time - deltaT);
1347 * VectorTools::create_right_hand_side(dof_handler,
1348 * QGauss<dim>(fe.degree+1),
1352 * forcing_terms.add(deltaT * (1 - theta), tmp);
1353 * system_rhs += forcing_terms;
1355 * system_matrix.copy_from(mass_matrix);
1356 * system_matrix.add(theta * deltaT, laplace_matrix);
1358 * constraints.condense (system_matrix, system_rhs);
1364 * If we are doing the method of manufactured solutions
1365 * then we set the boundary conditions to the exact solution.
1366 * Otherwise the boundary conditions are zero.
1369 * ExactValuesMFG<dim> boundary_values_function;
1371 * BoundaryValues<dim> boundary_values_function;
1373 * boundary_values_function.set_time(a_time);
1375 * std::map<types::global_dof_index, double> boundary_values;
1376 * VectorTools::interpolate_boundary_values(dof_handler,
1378 * boundary_values_function,
1381 * MatrixTools::apply_boundary_values(boundary_values,
1387 * solve_time_step(braid_data);
1391 * int HeatEquation<dim>::size() const
1393 * return dof_handler.n_dofs();
1398 * This function computes the error for the time step when doing
1399 * the method of manufactured solutions. First the exact values
1400 * is calculated, then the difference per cell is computed for
1401 * the various norms, and the error is computed. This is written
1402 * out to a pretty table.
1405 * template<int dim> void
1406 * HeatEquation<dim>::process_solution(double a_time,
1408 * const Vector<double>& a_vector)
1412 * Compute the exact value for the manufactured solution case
1415 * ExactValuesMFG<dim> exact_function;
1416 * exact_function.set_time(a_time);
1418 * Vector<double> difference_per_cell (triangulation.n_active_cells());
1419 * VectorTools::integrate_difference(dof_handler,
1422 * difference_per_cell,
1423 * QGauss<dim>(fe.degree+1),
1424 * VectorTools::L2_norm);
1426 * const double L2_error = VectorTools::compute_global_error(triangulation,
1427 * difference_per_cell,
1428 * VectorTools::L2_norm);
1430 * VectorTools::integrate_difference(dof_handler,
1433 * difference_per_cell,
1434 * QGauss<dim>(fe.degree+1),
1435 * VectorTools::H1_seminorm);
1437 * const double H1_error = VectorTools::compute_global_error(triangulation,
1438 * difference_per_cell,
1439 * VectorTools::H1_seminorm);
1441 * const QTrapezoid<1> q_trapez;
1442 * const QIterated<dim> q_iterated (q_trapez, 5);
1443 * VectorTools::integrate_difference (dof_handler,
1446 * difference_per_cell,
1448 * VectorTools::Linfty_norm);
1449 * const double Linfty_error = VectorTools::compute_global_error(triangulation,
1450 * difference_per_cell,
1451 * VectorTools::Linfty_norm);
1453 * const unsigned int n_active_cells = triangulation.n_active_cells();
1454 * const unsigned int n_dofs = dof_handler.n_dofs();
1456 * pout() << "Cycle " << a_index << ':
'
1458 * << " Number of active cells: "
1461 * << " Number of degrees of freedom: "
1465 * convergence_table.add_value("cycle", a_index);
1466 * convergence_table.add_value("cells", n_active_cells);
1467 * convergence_table.add_value("dofs", n_dofs);
1468 * convergence_table.add_value("L2", L2_error);
1469 * convergence_table.add_value("H1", H1_error);
1470 * convergence_table.add_value("Linfty", Linfty_error);
1472 * convergence_table.set_precision("L2", 3);
1473 * convergence_table.set_precision("H1", 3);
1474 * convergence_table.set_precision("Linfty", 3);
1476 * convergence_table.set_scientific("L2", true);
1477 * convergence_table.set_scientific("H1", true);
1478 * convergence_table.set_scientific("Linfty", true);
1480 * convergence_table.set_tex_caption("cells", "\\# cells");
1481 * convergence_table.set_tex_caption("dofs", "\\# dofs");
1482 * convergence_table.set_tex_caption("L2", "@fL^2@f-error");
1483 * convergence_table.set_tex_caption("H1", "@fH^1@f-error");
1484 * convergence_table.set_tex_caption("Linfty", "@fL^\\infty@f-error");
1486 * convergence_table.set_tex_format("cells", "r");
1487 * convergence_table.set_tex_format("dofs", "r");
1489 * std::cout << std::endl;
1490 * convergence_table.write_text(std::cout);
1492 * std::ofstream error_table_file("tex-conv-table.tex");
1493 * convergence_table.write_tex(error_table_file);
1498<a name="ann-src/Utilities.cc"></a>
1499<h1>Annotated version of src/Utilities.cc</h1>
1505 * #include "Utilities.hh"
1508 * #include <fstream>
1516 * The shared variables
1522 * static std::string s_pout_filename ;
1523 * static std::string s_pout_basename ;
1524 * static std::ofstream s_pout ;
1526 * static bool s_pout_init = false ;
1527 * static bool s_pout_open = false ;
1532 * in parallel, compute the filename give the basename
1533 * [NOTE: dont call this before MPI is initialized.]
1536 * static void setFileName()
1538 * static const size_t ProcnumSize = 1 + 10 + 1 ; //'.
' + 10digits + '\0
'
1539 * char procnum[ProcnumSize] ;
1540 * snprintf( procnum ,ProcnumSize ,".%d" ,procID);
1541 * s_pout_filename = s_pout_basename + procnum ;
1546 * in parallel, close the file if nec., open it and check for success
1549 * static void openFile()
1551 * if ( s_pout_open )
1555 * s_pout.open( s_pout_filename.c_str() );
1558 * if open() fails, we have problems, but it's better
1559 * to
try again later than to make believe it succeeded
1562 * s_pout_open = (
bool)s_pout ;
1571 *
static void setFileName()
1573 * s_pout_filename =
"cout" ;
1581 *
static void openFile()
1586 * std::ostream& pout()
1591 * the common
case is _open ==
true, which just returns s_pout
1594 *
if ( ! s_pout_open )
1598 * the uncommon cae: the file isn
't opened, MPI may not be
1599 * initialized, and the basename may not have been set
1602 * int flag_i, flag_f;
1603 * MPI_Initialized(&flag_i);
1604 * MPI_Finalized(&flag_f);
1607 * app hasn't
set a basename yet, so
set the
default
1610 *
if ( ! s_pout_init )
1612 * s_pout_basename =
"pout" ;
1613 * s_pout_init = true ;
1617 *
if MPI not initialized, we cant open the file so
return cout
1620 *
if ( ! flag_i || flag_f)
1626 * MPI is initialized, so file must not be, so open it
1633 *
finally, in
case the open failed,
return cout
1636 *
if ( ! s_pout_open )
1638 *
return std::cout ;
1649<a name=
"ann-src/Utilities.hh"></a>
1650<h1>Annotated version of src/
Utilities.hh</h1>
1656 * #ifndef _UTILITIES_H_
1657 * #define _UTILITIES_H_
1659 * #include <iostream>
1663 * This preprocessor macro is used on function arguments
1664 * that are not used in the function. It is used to
1665 * suppress compiler warnings.
1668 * #define UNUSED(x) (void)(x)
1672 * Contains the current MPI processor ID.
1675 *
extern int procID;
1679 *
Function to
return the ostream to write out to. In MPI
1680 * mode it returns a stream to a file named pout.<#> where
1681 * <#> is the procID. This allows the user to write output
1682 * from each processor to a separate file. In
serial mode
1683 * (no MPI), it returns the standard output.
1686 * std::ostream& pout();
1691<a name=
"ann-src/parallel_in_time.cc"></a>
1692<h1>Annotated version of src/parallel_in_time.cc</h1>
1717 * #include
"BraidFuncs.hh"
1718 * #include
"HeatEquation.hh"
1719 * #include
"Utilities.hh"
1721 * #include <fstream>
1722 * #include <iostream>
1724 *
int main(
int argc,
char *argv[])
1728 *
using namespace dealii;
1733 * MPI_Init(&argc, &argv);
1734 *
comm = MPI_COMM_WORLD;
1735 * MPI_Comm_rank(
comm, &rank);
1745 *
double tstart = 0.0;
1746 *
double tstop = 0.002;
1748 * my_App *app =
new(my_App);
1750 * braid_Init(MPI_COMM_WORLD,
comm, tstart, tstop, ntime, app,
1751 * my_Step, my_Init, my_Clone, my_Free, my_Sum, my_SpatialNorm,
1752 * my_Access, my_BufSize, my_BufPack, my_BufUnpack, &core);
1756 *
int max_levels = 3;
1763 *
double tol = 1.e-7;
1772 *
int min_coarse = 10;
1776 *
int wrapper_tests = 0;
1779 *
int print_level = 1;
1780 *
int access_level = 1;
1781 *
int use_sequential= 0;
1783 * braid_SetPrintLevel( core, print_level);
1784 * braid_SetAccessLevel( core, access_level);
1785 * braid_SetMaxLevels(core, max_levels);
1788 * braid_SetMinCoarse( core, min_coarse );
1789 * braid_SetSkip(core, skip);
1790 * braid_SetNRelax(core, -1, nrelax);
1793 * braid_SetAbsTol(core, tol);
1796 * braid_SetCFactor(core, -1, cfactor);
1799 * braid_SetMaxIter(core, max_iter);
1800 * braid_SetSeqSoln(core, use_sequential);
1803 * app->final_step = ntime;
1805 * braid_Drive(core);
1809 * Free the memory now that we are done
1812 * braid_Destroy(core);
1819 * MPI_Comm_free(&
comm);
1824 *
catch (std::exception &exc)
1826 * std::cerr << std::endl << std::endl
1827 * <<
"----------------------------------------------------"
1829 * std::cerr <<
"Exception on processing: " << std::endl << exc.what()
1830 * << std::endl <<
"Aborting!" << std::endl
1831 * <<
"----------------------------------------------------"
1838 * std::cerr << std::endl << std::endl
1839 * <<
"----------------------------------------------------"
1841 * std::cerr <<
"Unknown exception!" << std::endl <<
"Aborting!"
1843 * <<
"----------------------------------------------------"
1854<a name=
"ann-test/test_braid.cc"></a>
1855<h1>Annotated version of test/test_braid.cc</h1>
1861 * #include
"BraidFuncs.hh"
1863 * #include <braid.h>
1864 * #include <braid_test.h>
1866 * #include <iostream>
1868 *
int main(
int argc,
char** argv)
1872 * MPI_Init(&argc, &argv);
1873 *
comm = MPI_COMM_WORLD;
1874 * MPI_Comm_rank(
comm, &rank);
1876 * my_App *app =
new(my_App);
1879 *
double time = 0.2;
1881 * braid_Int init_access_result = braid_TestInitAccess(app,
1888 * (
void)init_access_result;
1890 * braid_Int clone_result = braid_TestClone(app,
1898 * (
void)clone_result;
1900 * braid_Int sum_result = braid_TestSum(app,
1911 * braid_Int norm_result = braid_TestSpatialNorm(app,
1920 * (
void)norm_result;
1922 * braid_Int buf_result = braid_TestBuf(app,
1938 * braid_SplitCommworld(&
comm, 1, &comm_x, &comm_t);
1942 * 2*(tstop-tstart)/ntime, my_Init, my_Free, my_Clone,
1943 * my_Sum, my_SpatialNorm, my_BufSize, my_BufPack,
1944 * my_BufUnpack, my_Coarsen, my_Interp, my_Residual, my_Step);
void set_flags(const FlagType &flags)
void initialize(const MatrixType &A, const AdditionalData ¶meters=AdditionalData())
__global__ void set(Number *val, const Number s, const size_type N)
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)
void hyper_L(Triangulation< dim > &tria, const double left=-1., const double right=1., const bool colorize=false)
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 >())
void create_laplace_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 >())
Point< spacedim > point(const gp_Pnt &p, const double tolerance=1e-10)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
std::vector< unsigned int > serial(const std::vector< unsigned int > &targets, const std::function< RequestType(const unsigned int)> &create_request, const std::function< AnswerType(const unsigned int, const RequestType &)> &answer_request, const std::function< void(const unsigned int, const AnswerType &)> &process_answer, const MPI_Comm comm)
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation
*** braid_TestAll(app, comm_x, stdout, 0.0,(tstop-tstart)/ntime, *2 *(tstop-tstart)/ntime, my_Init, my_Free, my_Clone, *my_Sum, my_SpatialNorm, my_BufSize, my_BufPack, *my_BufUnpack, my_Coarsen, my_Interp, my_Residual, my_Step)
****code * * MPI_Finalize()
*braid_SplitCommworld & comm
void advance(std::tuple< I1, I2 > &t, const unsigned int n)