deal.II version GIT relicensing-2173-gae8fc9d14b 2024-11-24 06:40:00+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
Distributed_Moving_Laser_Heating.h
Go to the documentation of this file.
1
267 *  
268 *  
269 * @endcode
270 *
271 *
272 * <a name="Distributed_Moving_Laser_Heating.cc-Includefiles"></a>
273 * <h3>Include files</h3>
274 *
275
276 *
277 * All the include files have already been discussed in previous tutorials.
278 *
279 * @code
280 *   #include <deal.II/dofs/dof_handler.h>
281 *   #include <deal.II/dofs/dof_renumbering.h>
282 *   #include <deal.II/grid/grid_generator.h>
283 *   #include <deal.II/grid/tria_accessor.h>
284 *   #include <deal.II/grid/tria_iterator.h>
285 *   #include <deal.II/dofs/dof_accessor.h>
286 *   #include <deal.II/fe/fe_q.h>
287 *   #include <deal.II/dofs/dof_tools.h>
288 *   #include <deal.II/fe/fe_values.h>
289 *   #include <deal.II/base/quadrature_lib.h>
290 *   #include <deal.II/base/function.h>
291 *   #include <deal.II/numerics/vector_tools.h>
292 *   #include <deal.II/numerics/matrix_tools.h>
293 *   #include <deal.II/lac/vector.h>
294 *   #include <deal.II/lac/full_matrix.h>
295 *   #include <deal.II/lac/dynamic_sparsity_pattern.h>
296 *  
297 *   #include <deal.II/grid/grid_in.h>
298 *   #include <deal.II/grid/grid_tools.h>
299 *   #include <deal.II/lac/trilinos_vector.h>
300 *   #include <deal.II/lac/trilinos_sparse_matrix.h>
301 *   #include <deal.II/lac/trilinos_solver.h>
302 *   #include <deal.II/lac/trilinos_precondition.h>
303 *  
304 *   #include <deal.II/lac/sparsity_tools.h>
305 *   #include <deal.II/lac/generic_linear_algebra.h>
306 *  
307 *   #include <deal.II/base/conditional_ostream.h>
308 *   #include <deal.II/base/utilities.h>
309 *   #include <deal.II/base/index_set.h>
310 *   #include <deal.II/distributed/tria.h>
311 *  
312 *   #include <deal.II/numerics/data_out.h>
313 *   #include <fstream>
314 *   #include <iostream>
315 *  
316 *  
317 *   #include <deal.II/base/logstream.h>
318 *   #include <deal.II/lac/affine_constraints.h>
319 *   #include <deal.II/base/timer.h>
320 *  
321 * @endcode
322 *
323 * grid refine
324 *
325 * @code
326 *   #include <deal.II/numerics/error_estimator.h>
327 *   #include <deal.II/distributed/grid_refinement.h>
328 *   #include <deal.II/distributed/solution_transfer.h>
329 *  
330 * @endcode
331 *
332 * remember to use the namespace dealii before
333 * defining a class that is inheritaged from Function<dim>
334 *
335 * @code
336 *   using namespace dealii;
337 *  
338 * @endcode
339 *
340 * In general, it is more clear to separate boundary and initial condictions,
341 * as well as the right hand side function from a file holding all the things.
342 * To do so, in this work, the globalPara.h file defines physical constants,
343 * laser parameters, and heat characteristics of materials involved. Boundary
344 * and initial conditions are defined in boundaryInit.h. The rightHandSide.h
345 * defines the heat source, which in this work is a moving Gaussian beam.
346 *
347
348 *
349 *
350 * @code
351 *   #ifndef GLOBAL_PARA
352 *   #define GLOBAL_PARA
353 *   #include "./globalPara.h"
354 *   #include "./boundaryInit.h"
355 *   #include "./rightHandSide.h"
356 *   #endif
357 *  
358 * @endcode
359 *
360 * Now the main class is defined as following
361 *
362 * @code
363 *   template <int dim>
364 *   class LaserHeating
365 *   {
366 *   public:
367 *   LaserHeating ();
368 *   ~LaserHeating ();
369 *   void run ();
370 *  
371 *   private:
372 *   void make_grid ();
373 *   void setup_system();
374 *  
375 *   void assemble_system_matrix_init (double time_step);
376 *   void dynamic_assemble_rhs_T (double time, double time_step);
377 *  
378 *   void solve_T ();
379 *  
380 *   void refine_mesh();
381 *   void output_results (int output_num) const;
382 *  
383 *   MPI_Comm mpi_communicator;
384 *  
386 *   FE_Q<dim> fe;
387 *   DoFHandler<dim> dof_handler;
388 *  
389 *   AffineConstraints<double> constraints_T;
390 *  
391 *  
392 * @endcode
393 *
394 * system_matrix
395 *
396 * @code
397 *   TrilinosWrappers::SparseMatrix system_matrix_T;
398 *  
399 * @endcode
400 *
401 * for storing left matrix
402 *
403 * @code
404 *   TrilinosWrappers::SparseMatrix left_system_matrix_T;
405 *  
406 * @endcode
407 *
408 * for storing right matrix
409 *
410 * @code
411 *   TrilinosWrappers::SparseMatrix right_system_matrix_T;
412 *  
413 * @endcode
414 *
415 * System_rhs, only locally owned cells
416 *
417 * @code
418 *   TrilinosWrappers::MPI::Vector system_rhs_T;
419 *  
420 * @endcode
421 *
422 * Solutions
423 * Old Solutions with ghost cells, for output
424 *
425 * @code
426 *   TrilinosWrappers::MPI::Vector old_solution_T;
427 *  
428 * @endcode
429 *
430 * Old Solutions only with locally owned cells
431 *
432 * @code
433 *   TrilinosWrappers::MPI::Vector old_solution_T_cal;
434 *  
435 * @endcode
436 *
437 * New Solutions only with locally owned cells
438 *
439 * @code
440 *   TrilinosWrappers::MPI::Vector new_solution_T;
441 *  
442 * @endcode
443 *
444 * Dynamic assembling of the righthandside terms
445 *
446 * @code
447 *   TrilinosWrappers::MPI::Vector dynamic_rhs_T;
448 *  
449 *  
450 *   IndexSet locally_owned_dofs;
451 *   IndexSet locally_relevant_dofs;
452 *  
453 *   ConditionalOStream pcout;
454 *   TimerOutput computing_timer;
455 *  
456 *   double theta;
457 *  
458 *  
459 *  
460 *   };
461 *  
462 * @endcode
463 *
464 * the constructor
465 *
466 * @code
467 *   template <int dim>
468 *   LaserHeating<dim>::LaserHeating ()
469 *   :
470 *   mpi_communicator (MPI_COMM_WORLD),
471 *   triangulation (mpi_communicator),
472 *   fe (1),
473 *   dof_handler (triangulation),
474 *   pcout (std::cout,Utilities::MPI::this_mpi_process(mpi_communicator) == 0),
475 *   computing_timer (mpi_communicator, pcout, TimerOutput::summary, TimerOutput::wall_times),
476 *   theta(0.5)
477 *   {}
478 *  
479 * @endcode
480 *
481 * the destructor
482 *
483 * @code
484 *   template <int dim>
485 *   LaserHeating<dim>::~LaserHeating ()
486 *   {
487 *   dof_handler.clear();
488 *   }
489 *  
490 * @endcode
491 *
492 *
493 * <a name="Distributed_Moving_Laser_Heating.cc-LaserHeatingmake_grid"></a>
494 * <h4>LaserHeating::make_grid</h4>
495 * make grid by importing msh file, and rescale
496 *
497 * @code
498 *   template <int dim>
499 *   void LaserHeating<dim>::make_grid ()
500 *   {
501 *   TimerOutput::Scope t(computing_timer,"make_grid()");
502 *  
503 *   GridIn<dim> grid_in;
504 *   grid_in.attach_triangulation (triangulation);
505 *   std::ifstream input_file ("geometry.msh");
506 *   grid_in.read_msh (input_file);
508 *  
509 *   pcout << " Number of active cells: "
510 *   << triangulation.n_global_active_cells()
511 *   << std::endl
512 *   << " Total number of cells: "
513 *   << triangulation.n_cells()
514 *   << std::endl;
515 *   }
516 *  
517 * @endcode
518 *
519 *
520 * <a name="Distributed_Moving_Laser_Heating.cc-LaserHeatingsetup_system"></a>
521 * <h4>LaserHeating::setup_system</h4>
522 * initialization
523 *
524 * @code
525 *   template <int dim>
526 *   void LaserHeating<dim>::setup_system ()
527 *   {
528 *  
529 *   TimerOutput::Scope t(computing_timer,"setup_system()");
530 *  
531 *   dof_handler.distribute_dofs (fe);
532 *  
533 *   pcout << " Number of degrees of freedom: "
534 *   << dof_handler.n_dofs()
535 *   << std::endl;
536 *  
537 *   locally_owned_dofs = dof_handler.locally_owned_dofs();
538 *   locally_relevant_dofs = DoFTools::extract_locally_relevant_dofs (dof_handler);
539 *  
540 * @endcode
541 *
542 * we want to output solution, so here should have ghost cells
543 *
544 * @code
545 *   old_solution_T.reinit (locally_owned_dofs,locally_relevant_dofs,mpi_communicator);
546 *  
547 * @endcode
548 *
549 * locally owned cells
550 *
551 * @code
552 *   old_solution_T_cal.reinit (locally_owned_dofs,mpi_communicator);
553 *   new_solution_T.reinit (locally_owned_dofs,mpi_communicator);
554 *   dynamic_rhs_T.reinit (locally_owned_dofs,mpi_communicator);
555 *   system_rhs_T.reinit (locally_owned_dofs,mpi_communicator);
556 *  
557 *   constraints_T.clear();
558 *   constraints_T.reinit (locally_relevant_dofs);
559 *   DoFTools::make_hanging_node_constraints (dof_handler, constraints_T);
560 *   constraints_T.close();
561 *  
562 *   const unsigned int myid = Utilities::MPI::this_mpi_process (mpi_communicator);
563 *   DynamicSparsityPattern dsp_T(locally_relevant_dofs);
564 *   DoFTools::make_sparsity_pattern (dof_handler, dsp_T, constraints_T, false, myid);
565 *  
567 *   locally_owned_dofs,
568 *   mpi_communicator,
569 *   locally_relevant_dofs);
570 *  
571 *   left_system_matrix_T.reinit (locally_owned_dofs,locally_owned_dofs,dsp_T,mpi_communicator);
572 *   right_system_matrix_T.reinit (locally_owned_dofs,locally_owned_dofs,dsp_T,mpi_communicator);
573 *   system_matrix_T.reinit (locally_owned_dofs,locally_owned_dofs,dsp_T,mpi_communicator);
574 *  
575 *   }
576 *  
577 *  
578 * @endcode
579 *
580 *
581 * <a name="Distributed_Moving_Laser_Heating.cc-LaserHeatingassemble_system_matrix"></a>
582 * <h4>LaserHeating::assemble_system_matrix</h4>
583 *
584
585 *
586 *
587 * @code
588 *   template <int dim>
589 *   void LaserHeating<dim>::assemble_system_matrix_init (double time_step)
590 *   {
591 *  
592 *   TimerOutput::Scope t(computing_timer,"assemble_system_matrix_init()");
593 *  
594 *   QGauss<dim> quadrature_formula(2);
595 *  
596 *  
597 *   const InitialValues<dim> initial_value_func_T;
598 *  
599 *  
600 *   const RhoC<dim> rho_C_fun_T;
601 *   const K_T<dim> k_fun_T;
602 *  
603 *  
604 *   FEValues<dim> fe_values (fe, quadrature_formula,
607 *  
608 *   const unsigned int dofs_per_cell = fe.dofs_per_cell;
609 *   const unsigned int n_q_points = quadrature_formula.size();
610 *  
611 *  
612 *   FullMatrix<double> local_init_matrix (dofs_per_cell, dofs_per_cell);
613 *   Vector<double> local_init_T_rhs (dofs_per_cell);
614 *  
615 *   FullMatrix<double> local_rho_c_T_matrix (dofs_per_cell, dofs_per_cell);
616 *   FullMatrix<double> local_k_T_matrix (dofs_per_cell, dofs_per_cell);
617 *  
618 *  
619 *   std::vector<types::global_dof_index> local_dof_indices (dofs_per_cell);
620 *  
621 *   system_matrix_T = 0;
622 *   left_system_matrix_T = 0;
623 *   right_system_matrix_T = 0;
624 *  
625 *   system_rhs_T = 0;
626 *  
627 *   for (const auto &cell : dof_handler.active_cell_iterators())
628 *   if(cell->is_locally_owned())
629 *   {
630 *  
631 *   fe_values.reinit (cell);
632 *   local_init_matrix = 0;
633 *  
634 *   local_rho_c_T_matrix = 0;
635 *   local_k_T_matrix = 0;
636 *  
637 *   local_init_T_rhs = 0;
638 *  
639 *   for (unsigned int q=0; q<n_q_points; ++q)
640 *   for (unsigned int i=0; i<dofs_per_cell; ++i)
641 *   {
642 *   const Tensor<1,dim> div_phi_i_u = fe_values.shape_grad (i,q);
643 *   const double phi_i_u = fe_values.shape_value (i,q);
644 *  
645 *   for (unsigned int j=0; j<dofs_per_cell; ++j)
646 *   {
647 *  
648 *   const Tensor<1,dim> div_phi_j_u = fe_values.shape_grad(j,q);
649 *   const double phi_j_u = fe_values.shape_value (j,q);
650 *  
651 *   local_init_matrix(i,j) += (phi_i_u *
652 *   phi_j_u *
653 *   fe_values.JxW (q));
654 *  
655 *   local_rho_c_T_matrix(i,j) += (rho_C_fun_T.value(fe_values.quadrature_point(q)) *
656 *   phi_i_u *
657 *   phi_j_u *
658 *   fe_values.JxW (q))
659 *   +
660 *   time_step * (theta) *
661 *   (k_fun_T.value(fe_values.quadrature_point(q)) *
662 *   div_phi_i_u *
663 *   div_phi_j_u *
664 *   fe_values.JxW (q));
665 *  
666 *   local_k_T_matrix(i,j) += (rho_C_fun_T.value(fe_values.quadrature_point(q)) *
667 *   phi_i_u *
668 *   phi_j_u *
669 *   fe_values.JxW (q))
670 *   -
671 *   time_step * (1.0-theta) *
672 *   (k_fun_T.value(fe_values.quadrature_point(q)) *
673 *   div_phi_i_u *
674 *   div_phi_j_u *
675 *   fe_values.JxW (q));
676 *  
677 *   }
678 *  
679 *   local_init_T_rhs(i) += (phi_i_u *
680 *   initial_value_func_T.value (fe_values.quadrature_point (q)) *
681 *   fe_values.JxW (q));
682 *  
683 *   }
684 *  
685 *   cell->get_dof_indices (local_dof_indices);
686 *  
687 * @endcode
688 *
689 * copy to system_matrix_T and system_rhs_T for projecting initial values
690 *
691 * @code
692 *   constraints_T.distribute_local_to_global(local_init_matrix,
693 *   local_init_T_rhs,
694 *   local_dof_indices,
695 *   system_matrix_T,
696 *   system_rhs_T);
697 *  
698 *  
699 * @endcode
700 *
701 * store M + dt*theta*A as the left_system_matrix
702 *
703
704 *
705 *
706 * @code
707 *   constraints_T.distribute_local_to_global(local_rho_c_T_matrix,
708 *   local_dof_indices,
709 *   left_system_matrix_T);
710 *  
711 * @endcode
712 *
713 * store M - dt*(1-theta)*A as the right_system_matrix
714 *
715 * @code
716 *   constraints_T.distribute_local_to_global(local_k_T_matrix,
717 *   local_dof_indices,
718 *   right_system_matrix_T);
719 *  
720 *  
721 *   }
722 *  
723 *   system_matrix_T.compress(VectorOperation::add);
724 *   left_system_matrix_T.compress(VectorOperation::add);
725 *   right_system_matrix_T.compress(VectorOperation::add);
726 *   system_rhs_T.compress(VectorOperation::add);
727 *  
728 *   }
729 *  
730 *  
731 * @endcode
732 *
733 *
734 * <a name="Distributed_Moving_Laser_Heating.cc-LaserHeatingdynamic_assemble_rhs_T"></a>
735 * <h4>LaserHeating::dynamic_assemble_rhs_T</h4>
736 * The right hand side is assembled each time during running, which is necessary as
737 * the laser source is moving. To separate the heat source and the right hand
738 * side assembling, the right hand side function is defined as RightHandside<dim>.
739 *
740 * @code
741 *   template <int dim>
742 *   void LaserHeating<dim>::dynamic_assemble_rhs_T (double time, double time_step)
743 *   {
744 *  
745 *   TimerOutput::Scope t(computing_timer,"assemble_rhs_T()");
746 *  
747 *   QGauss<dim> quadrature_formula(2);
748 *  
749 *   RightHandside<dim> rhs_func_T_1;
750 *   rhs_func_T_1.set_time(time);
751 *  
752 *   RightHandside<dim> rhs_func_T_2;
753 *   rhs_func_T_2.set_time(time-time_step);
754 *  
755 *   FEValues<dim> fe_values (fe, quadrature_formula,
756 *   update_values |
758 *  
759 *  
760 *   const unsigned int dofs_per_cell = fe.dofs_per_cell;
761 *   const unsigned int n_q_points = quadrature_formula.size();
762 *  
763 *   Vector<double> local_rhs_vector_T (dofs_per_cell);
764 *  
765 *   std::vector<types::global_dof_index> local_dof_indices (dofs_per_cell);
766 *  
767 *   std::vector<double> Rnp_cal_assemble (n_q_points);
768 *  
769 *  
770 *   dynamic_rhs_T = 0 ;
771 *  
773 *   cell = dof_handler.begin_active(),
774 *   endc = dof_handler.end();
775 *  
776 *   for (; cell!=endc; ++cell)
777 *   if(cell->is_locally_owned())
778 *   {
779 *   fe_values.reinit (cell);
780 *   local_rhs_vector_T = 0;
781 *  
782 *   for (unsigned int q=0; q<n_q_points; ++q)
783 *   for (unsigned int i=0; i<dofs_per_cell; ++i)
784 *   {
785 *   const double phi_i_u = fe_values.shape_value (i,q);
786 *  
787 *  
788 *   local_rhs_vector_T(i) += time_step * theta *
789 *   (phi_i_u *
790 *   rhs_func_T_1.value_v2 (fe_values.quadrature_point (q)) *
791 *   fe_values.JxW (q))
792 *   +
793 *   time_step * (1.0 - theta) *
794 *   (phi_i_u *
795 *   rhs_func_T_2.value_v2 (fe_values.quadrature_point (q)) *
796 *   fe_values.JxW (q));
797 *   }
798 *  
799 *   cell->get_dof_indices (local_dof_indices);
800 *  
801 *  
802 *   constraints_T.distribute_local_to_global(local_rhs_vector_T,
803 *   local_dof_indices,
804 *   dynamic_rhs_T);
805 *  
806 *   }
807 *  
808 *   dynamic_rhs_T.compress(VectorOperation::add);
809 *  
810 *  
811 *   }
812 *  
813 *  
814 * @endcode
815 *
816 *
817 * <a name="Distributed_Moving_Laser_Heating.cc-LaserHeatingsolve"></a>
818 * <h4>LaserHeating::solve</h4>
819 * Solving the equation is direct. Recall that we have defined several matrices and vectors,
820 * to avoid ambiguous, here, we only use system_matrix_T as the system matrix, system_rhs_T
821 * as the system right hand side. The vector completely_distributed_solution is used to store
822 * the obtained solution.
823 *
824 * @code
825 *   template <int dim>
826 *   void LaserHeating<dim>::solve_T ()
827 *   {
828 *   TimerOutput::Scope t(computing_timer,"solve_T()");
829 *  
830 *   TrilinosWrappers::MPI::Vector completely_distributed_solution (locally_owned_dofs,mpi_communicator);
831 *   SolverControl solver_control (1*system_rhs_T.size(),1e-12*system_rhs_T.l2_norm(),true);
832 *  
833 *   TrilinosWrappers::SolverCG solver (solver_control);
834 *  
835 *   TrilinosWrappers::PreconditionAMG preconditioner;
837 *  
838 *   preconditioner.initialize(system_matrix_T,data);
839 *  
840 *   solver.solve (system_matrix_T,completely_distributed_solution,system_rhs_T,preconditioner);
841 *  
842 *  
843 * @endcode
844 *
845 * Print the number of iterations by hand.
846 *
847
848 *
849 *
850 * @code
851 *   pcout << " " << solver_control.last_step()
852 *   << " CG iterations needed to obtain convergence." << std::endl
853 *   << "\t initial convergence value = " << solver_control.initial_value() << std::endl
854 *   << "\t final convergence value = " << solver_control.last_value() << std::endl
855 *   << std::endl;
856 *  
857 *   constraints_T.distribute (completely_distributed_solution);
858 *   new_solution_T = completely_distributed_solution;
859 *  
860 *   }
861 *  
862 *  
863 * @endcode
864 *
865 *
866 * <a name="Distributed_Moving_Laser_Heating.cc-LaserHeatingrefine_mesh"></a>
867 * <h4>LaserHeating::refine_mesh</h4>
868 *
869
870 *
871 *
872 * @code
873 *   template <int dim>
874 *   void LaserHeating<dim>::refine_mesh()
875 *   {
876 *  
877 *   TimerOutput::Scope t(computing_timer,"refine_mesh_at_beginning");
878 *  
879 *  
880 *   QGauss<dim> quadrature_formula(2);
881 *  
882 *   FEValues<dim> fe_values (fe, quadrature_formula,update_quadrature_points);
883 *  
884 *  
885 * @endcode
886 *
887 * only refine mesh 5um above the TiO2 and glass interface
888 *
889
890 *
891 *
892 * @code
894 *   cell = triangulation.begin_active();
895 *   cell != triangulation.end(); ++cell)
896 *   if(cell->is_locally_owned())
897 *   {
898 *   fe_values.reinit(cell);
899 *   if(std::abs(fe_values.quadrature_point(0)[1]) <= global_film_thickness+5e-6)
900 *   {
901 *   cell->set_refine_flag();
902 *   }
903 *   else
904 *   {
905 *   cell->clear_refine_flag();
906 *   }
907 *   }
908 *   triangulation.execute_coarsening_and_refinement();
909 *  
910 *   }
911 *  
912 *  
913 * @endcode
914 *
915 *
916 * <a name="Distributed_Moving_Laser_Heating.cc-LaserHeatinghoutput_results"></a>
917 * <h4>LaserHeatingh::output_results</h4>
918 *
919
920 *
921 *
922 * @code
923 *   template <int dim>
924 *   void LaserHeating<dim>::output_results (int output_num) const
925 *   {
926 *  
927 *   DataOut<dim> data_out;
928 *  
929 *   data_out.attach_dof_handler (dof_handler);
930 *   data_out.add_data_vector (old_solution_T, "T");
931 *  
932 * @endcode
933 *
934 * the length of output numbering
935 *
936
937 *
938 *
939 * @code
940 *   int step_N = 7;
941 *  
942 *   data_out.build_patches ();
943 *  
944 *   const std::string filename = ("solution-" +
945 *   Utilities::int_to_string (output_num, step_N) +
946 *   "." +
947 *   Utilities::int_to_string (triangulation.locally_owned_subdomain(),4) +
948 *   ".vtu");
949 *   std::ofstream output (filename.c_str());
950 *   data_out.write_vtu (output);
951 *  
952 *  
953 * @endcode
954 *
955 * output the overall solution
956 *
957
958 *
959 *
960 * @code
961 *   if (Utilities::MPI::this_mpi_process(mpi_communicator) == 0)
962 *   {
963 *   std::vector<std::string> filenames;
964 *   for (unsigned int i=0;i<Utilities::MPI::n_mpi_processes(mpi_communicator);++i)
965 *   filenames.push_back ("solution-" +
966 *   Utilities::int_to_string (output_num, step_N) +
967 *   "." +
968 *   Utilities::int_to_string (i,4) +
969 *   ".vtu");
970 *   std::ofstream master_output (("solution-" +
971 *   Utilities::int_to_string (output_num,step_N)+
972 *   ".pvtu").c_str());
973 *   data_out.write_pvtu_record (master_output,filenames);
974 *  
975 *   }
976 *  
977 *   }
978 *  
979 *  
980 *  
981 *  
982 * @endcode
983 *
984 *
985 * <a name="Distributed_Moving_Laser_Heating.cc-LaserHeatingrun"></a>
986 * <h4>LaserHeating::run</h4>
987 *
988
989 *
990 * This is the function which has the top-level control over everything. Apart
991 * from one line of additional output, it is the same as for the previous
992 * example.
993 *
994 * @code
995 *   template <int dim>
996 *   void LaserHeating<dim>::run ()
997 *   {
998 *   pcout << "Solving problem in " << dim << " space dimensions." << std::endl;
999 *  
1000 *  
1001 *   make_grid();
1002 *   refine_mesh();
1003 *   setup_system ();
1004 *   assemble_system_matrix_init (global_simulation_time_step);
1005 *  
1006 * @endcode
1007 *
1008 * projection of initial conditions by solving.
1009 * solution stored in new_solution_T;
1010 *
1011
1012 *
1013 *
1014 * @code
1015 *   solve_T ();
1016 *  
1017 *   old_solution_T = new_solution_T;
1018 *   old_solution_T_cal = new_solution_T;
1019 *  
1020 * @endcode
1021 *
1022 * reinitialization
1023 *
1024
1025 *
1026 *
1027 * @code
1028 *   system_matrix_T = 0;
1029 *   system_rhs_T = 0;
1030 *  
1031 *  
1032 *   double time_step = global_simulation_time_step;
1033 *   double time = 0;
1034 *   int timestep_number = 0;
1035 *  
1036 * @endcode
1037 *
1038 * output initial values; need ghost cells
1039 *
1040 * @code
1041 *   output_results (0);
1042 *  
1043 *  
1044 *   while(time < global_simulation_end_time)
1045 *   {
1046 *  
1047 *   time += time_step;
1048 *   timestep_number ++;
1049 *  
1050 *   pcout << "Time step " << timestep_number
1051 *   << " at t=" << time
1052 *   << " time_step = " << time_step
1053 *   << std::endl;
1054 *  
1055 * @endcode
1056 *
1057 * the dynamic solving part
1058 *
1059 * @code
1060 *   {
1061 *  
1062 *   right_system_matrix_T.vmult(system_rhs_T,old_solution_T_cal);
1063 *  
1064 *   dynamic_assemble_rhs_T (time,time_step);
1065 *   system_rhs_T.add(1,dynamic_rhs_T);
1066 *  
1067 *   system_matrix_T.copy_from (left_system_matrix_T);
1068 *  
1069 *   {
1070 *   BoundaryValues<dim> boundary_values_function;
1071 *   std::map<types::global_dof_index,double> boundary_values;
1072 *  
1074 *   BOUNDARY_NUM,
1075 *   boundary_values_function,
1076 *   boundary_values);
1077 *  
1078 *   MatrixTools::apply_boundary_values (boundary_values,
1079 *   system_matrix_T,
1080 *   new_solution_T,
1081 *   system_rhs_T,
1082 *   false);
1083 *   }
1084 *  
1085 *  
1086 *   solve_T ();
1087 *  
1088 * @endcode
1089 *
1090 * old_solution_T is used for output, holding ghost cells
1091 * old_solution_T_cal is used for calculation, holding only
1092 * locally owned cells.
1093 *
1094 * @code
1095 *   old_solution_T = new_solution_T;
1096 *   old_solution_T_cal = new_solution_T;
1097 *  
1098 *   if (Utilities::MPI::n_mpi_processes(mpi_communicator) <= 96 && (timestep_number % 50 == 0 ))
1099 *   {
1100 *   TimerOutput::Scope t(computing_timer,"output");
1101 *   output_results (timestep_number);
1102 *   }
1103 *  
1104 *   computing_timer.print_summary ();
1105 *   computing_timer.reset();
1106 *  
1107 *   pcout << std::endl;
1108 *  
1109 *   }
1110 *   }
1111 *  
1112 *   }
1113 *  
1114 *  
1115 * @endcode
1116 *
1117 *
1118 * <a name="Distributed_Moving_Laser_Heating.cc-Thecodemaincodefunction"></a>
1119 * <h3>The <code>main</code> function</h3>
1120 *
1121
1122 *
1123 *
1124 * @code
1125 *   int main (int argc, char *argv[])
1126 *   {
1127 *   try
1128 *   {
1129 *   Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1);
1130 *  
1131 *   LaserHeating<2> laserHeating_2d;
1132 *   laserHeating_2d.run ();
1133 *  
1134 *  
1135 *   }
1136 *   catch (std::exception &exc)
1137 *   {
1138 *   std::cerr << std::endl
1139 *   << std::endl
1140 *   << "----------------------------------------------------"
1141 *   << std::endl;
1142 *   std::cerr << "Exception on processing: " << std::endl
1143 *   << exc.what() << std::endl
1144 *   << "Aborting!" << std::endl
1145 *   << "----------------------------------------------------"
1146 *   << std::endl;
1147 *  
1148 *   return 1;
1149 *   }
1150 *   catch (...)
1151 *   {
1152 *   std::cerr << std::endl
1153 *   << std::endl
1154 *   << "----------------------------------------------------"
1155 *   << std::endl;
1156 *   std::cerr << "Unknown exception!" << std::endl
1157 *   << "Aborting!" << std::endl
1158 *   << "----------------------------------------------------"
1159 *   << std::endl;
1160 *   return 1;
1161 *   }
1162 *  
1163 *  
1164 *   return 0;
1165 *   }
1166 * @endcode
1167
1168
1169<a name="ann-boundaryInit.h"></a>
1170<h1>Annotated version of boundaryInit.h</h1>
1171 *
1172 *
1173 *
1174 *
1175 * @code
1176 *   /* -----------------------------------------------------------------------------
1177 *   *
1178 *   * SPDX-License-Identifier: LGPL-2.1-or-later
1179 *   * Copyright (C) 2021 by Hongfeng Ma
1180 *   * Copyright (C) 2021 by Tatiana E. Itina
1181 *   *
1182 *   * This file is part of the deal.II code gallery.
1183 *   *
1184 *   * -----------------------------------------------------------------------------
1185 *   */
1186 *  
1187 * @endcode
1188 *
1189 * #----------------------------------------------------------
1190 * #
1191 * # This file defines the boundary and initial conditions
1192 * #
1193 * #----------------------------------------------------------
1194 *
1195
1196 *
1197 *
1198 * @code
1199 *   #ifndef GLOBAL_PARA
1200 *   #define GLOBAL_PARA
1201 *   #include "./globalPara.h"
1202 *   #endif
1203 *  
1204 * @endcode
1205 *
1206 * #----------------------------------------------------------
1207 * # Declaration
1208 *
1209
1210 *
1211 *
1212 * @code
1213 *   template <int dim>
1214 *   class BoundaryValues : public Function<dim>
1215 *   {
1216 *   public:
1217 *   BoundaryValues () : Function<dim>() {}
1218 *  
1219 *   virtual double value (const Point<dim> &p,
1220 *   const unsigned int component = 0) const override;
1221 *   };
1222 *  
1223 *   template <int dim>
1224 *   class InitialValues : public Function<dim>
1225 *   {
1226 *   public:
1227 *   InitialValues () : Function<dim>() {}
1228 *  
1229 *   virtual double value (const Point<dim> &p,
1230 *   const unsigned int component = 0) const override;
1231 *   };
1232 *  
1233 *  
1234 * @endcode
1235 *
1236 * #----------------------------------------------------------
1237 * # Implementation
1238 *
1239
1240 *
1241 *
1242 * @code
1243 *   template <int dim>
1244 *   double BoundaryValues<dim>::value (const Point<dim> &/*p*/,
1245 *   const unsigned int /*component*/) const
1246 *   {
1247 *   return 293;
1248 *   }
1249 *  
1250 *  
1251 *   template <int dim>
1252 *   double InitialValues<dim>::value (const Point<dim> &/*p*/,
1253 *   const unsigned int /*component*/) const
1254 *   {
1255 *   return 293;
1256 *   }
1257 *  
1258 *  
1259 *  
1260 *  
1261 *  
1262 * @endcode
1263 *
1264 * #----------------------------------------------------------
1265 * # Declaration and Implementation
1266 * # mass density and heat capacity
1267 *
1268
1269 *
1270 *
1271 * @code
1272 *   template <int dim>
1273 *   class RhoC : public Function<dim>
1274 *   {
1275 *   public:
1276 *   RhoC () : Function<dim>() {}
1277 *  
1278 *   virtual double value (const Point<dim> &p,
1279 *   const unsigned int component = 0) const override;
1280 *   };
1281 *  
1282 *   template <int dim>
1283 *   double RhoC<dim>::value (const Point<dim> &p,
1284 *   const unsigned int /*component*/) const
1285 *   {
1286 * @endcode
1287 *
1288 * # p stores the xyz coordinates at each vertex
1289 * # for 2D problems in xy, we assume the non-uniform is in y-axis.
1290 *
1291 * @code
1292 *   if ( p[1] >= -global_film_thickness )
1293 *   {
1294 *   return global_rho_Tio2 * global_C_Tio2;
1295 *   }
1296 *   else
1297 *   return global_rho_glass * global_C_glass;
1298 *   }
1299 *  
1300 *  
1301 *  
1302 *  
1303 * @endcode
1304 *
1305 * #----------------------------------------------------------
1306 * # Declaration and Implementation
1307 * # thermal conductivity
1308 *
1309
1310 *
1311 *
1312 * @code
1313 *   template <int dim>
1314 *   class K_T : public Function<dim>
1315 *   {
1316 *   public:
1317 *   K_T () : Function<dim>() {}
1318 *  
1319 *   virtual double value (const Point<dim> &p,
1320 *   const unsigned int component = 0) const override;
1321 *   };
1322 *  
1323 *   template <int dim>
1324 *   double K_T<dim>::value (const Point<dim> &p,
1325 *   const unsigned int /*component*/) const
1326 *   {
1327 * @endcode
1328 *
1329 * # p stores the xyz coordinates at each vertex
1330 * # for 2D problems in xy, we assume the non-uniform is in y-axis.
1331 *
1332 * @code
1333 *   if ( p[1] >= -global_film_thickness)
1334 *   {
1335 *   return global_k_Tio2;
1336 *   }
1337 *   else
1338 *   return global_k_glass;
1339 *   }
1340 *  
1341 * @endcode
1342
1343
1344<a name="ann-globalPara.h"></a>
1345<h1>Annotated version of globalPara.h</h1>
1346 *
1347 *
1348 *
1349 *
1350 * @code
1351 *   /* -----------------------------------------------------------------------------
1352 *   *
1353 *   * SPDX-License-Identifier: LGPL-2.1-or-later
1354 *   * Copyright (C) 2021 by Hongfeng Ma
1355 *   * Copyright (C) 2021 by Tatiana E. Itina
1356 *   *
1357 *   * This file is part of the deal.II code gallery.
1358 *   *
1359 *   * -----------------------------------------------------------------------------
1360 *   */
1361 *  
1362 * @endcode
1363 *
1364 * # physics constants
1365 *
1366 * @code
1367 *   double global_PI = 3.1415927;
1368 *  
1369 * @endcode
1370 *
1371 * # Laser
1372 *
1373 * @code
1374 *   double global_Pow_laser = 0.4; // power [W]
1375 *   double global_spotsize_at_e_2 = 20e-6; // laser spot size at e^(-2) [m]
1376 *   double global_c_laser = global_spotsize_at_e_2 / 4.0; // C parameter in Gaussian func, [m]
1377 *   double global_c_hwhm = global_c_laser * 2.35482 / 2; // HWHM, [m]
1378 *   double global_V_scan_x = 10e-3; // scan speed, [m/s]
1379 *  
1380 *   double global_init_position_x0 = -50e-6; // initial spot center position
1381 *  
1382 * @endcode
1383 *
1384 * # material
1385 * thin film
1386 *
1387 * @code
1388 *   double global_rho_Tio2 = 4200; // mass density, [kg/m^3]
1389 *   double global_C_Tio2 = 690; // heat capacity, [J/kg/K]
1390 *   double global_k_Tio2 = 4.8; // thermal conductivity, [W/m/K]
1391 * @endcode
1392 *
1393 * substrate
1394 *
1395 * @code
1396 *   double global_rho_glass = 2200;
1397 *   double global_C_glass = 700;
1398 *   double global_k_glass = 1.8;
1399 *  
1400 *   double global_film_thickness = 400e-9; // film thickness, [m]
1401 *  
1402 * @endcode
1403 *
1404 * # simulation time
1405 *
1406 * @code
1407 *   double global_simulation_time_step = 1e-5; // 10 [us]
1408 *   double global_simulation_end_time = 100e-6 / global_V_scan_x; // 100 [um] / scan speed
1409 *  
1410 * @endcode
1411 *
1412 * # about the MESH
1413 *
1414 * @code
1415 *   #define BOUNDARY_NUM 11
1416 * @endcode
1417
1418
1419<a name="ann-rightHandSide.h"></a>
1420<h1>Annotated version of rightHandSide.h</h1>
1421 *
1422 *
1423 *
1424 *
1425 * @code
1426 *   /* -----------------------------------------------------------------------------
1427 *   *
1428 *   * SPDX-License-Identifier: LGPL-2.1-or-later
1429 *   * Copyright (C) 2021 by Hongfeng Ma
1430 *   * Copyright (C) 2021 by Tatiana E. Itina
1431 *   *
1432 *   * This file is part of the deal.II code gallery.
1433 *   *
1434 *   * -----------------------------------------------------------------------------
1435 *   */
1436 *  
1437 * @endcode
1438 *
1439 * #----------------------------------------------------------
1440 * #
1441 * # This file defines the boundary and initial conditions
1442 * #
1443 * #----------------------------------------------------------
1444 *
1445
1446 *
1447 *
1448 * @code
1449 *   #ifndef GLOBAL_PARA
1450 *   #define GLOBAL_PARA
1451 *   #include "./globalPara.h"
1452 *   #endif
1453 *  
1454 * @endcode
1455 *
1456 * #----------------------------------------------------------
1457 * # Declaration
1458 *
1459
1460 *
1461 *
1462 * @code
1463 *   template <int dim>
1464 *   class RightHandside : public Function<dim>
1465 *   {
1466 *   public:
1467 *   RightHandside () : Function<dim>() {}
1468 *  
1469 *   double value_v2 (const Point<dim> &p);
1470 *   };
1471 *  
1472 * @endcode
1473 *
1474 * #----------------------------------------------------------
1475 * # Implementation
1476 *
1477
1478 *
1479 *
1480 * @code
1481 *   template <int dim>
1482 *   double RightHandside<dim>::value_v2 (const Point<dim> &p)
1483 *   {
1484 *  
1485 *   double alpha_abs = 1e4;
1486 *  
1487 *  
1488 *   if(p[1] >= -global_film_thickness)
1489 *   {
1490 *  
1491 *   double P00 = global_Pow_laser / global_PI / global_c_laser / global_c_laser / 2.0;
1492 *  
1493 *   double I00 = P00 * std::exp(-
1494 *   (
1495 *   (p[0] - global_V_scan_x * this->get_time()-global_init_position_x0) *
1496 *   (p[0] - global_V_scan_x * this->get_time()-global_init_position_x0)
1497 *   ) /
1498 *   (2.0 * global_c_laser * global_c_laser) );
1499 *  
1500 *  
1501 *   return alpha_abs * I00 * std::exp(-alpha_abs*(0 - p[1]));
1502 *  
1503 *   }
1504 *  
1505 *   else
1506 *   {
1507 * @endcode
1508 *
1509 * # no absorption
1510 *
1511 * @code
1512 *   return 0;
1513 *   }
1514 *  
1515 *   }
1516 *  
1517 *  
1518 * @endcode
1519
1520
1521*/
void attach_dof_handler(const DoFHandler< dim, spacedim > &)
Definition fe_q.h:554
virtual RangeNumberType value(const Point< dim > &p, const unsigned int component=0) const
void attach_triangulation(Triangulation< dim, spacedim > &tria)
Definition grid_in.cc:153
Definition point.h:111
@ wall_times
Definition timer.h:651
unsigned int level
Definition grid_out.cc:4626
typename ActiveSelector::active_cell_iterator active_cell_iterator
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={}, 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.
std::vector< index_type > data
Definition mpi.cc:735
const Event initial
Definition event.cc:64
IndexSet extract_locally_relevant_dofs(const DoFHandler< dim, spacedim > &dof_handler)
void refine(Triangulation< dim, spacedim > &tria, const Vector< Number > &criteria, const double threshold, const unsigned int max_to_mark=numbers::invalid_unsigned_int)
void scale(const double scaling_factor, Triangulation< dim, spacedim > &triangulation)
@ matrix
Contents is actually a matrix.
@ general
No special properties.
void apply_boundary_values(const std::map< types::global_dof_index, number > &boundary_values, SparseMatrix< number > &matrix, Vector< number > &solution, Vector< number > &right_hand_side, const bool eliminate_columns=true)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
void distribute_sparsity_pattern(DynamicSparsityPattern &dsp, const IndexSet &locally_owned_rows, const MPI_Comm mpi_comm, const IndexSet &locally_relevant_rows)
unsigned int n_mpi_processes(const MPI_Comm mpi_communicator)
Definition mpi.cc:92
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
Definition mpi.cc:107
std::string get_time()
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
Definition utilities.cc:470
void interpolate_boundary_values(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof, const std::map< types::boundary_id, const Function< spacedim, number > * > &function_map, std::map< types::global_dof_index, number > &boundary_values, const ComponentMask &component_mask={})
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)
void copy(const T *begin, const T *end, U *dest)
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
::VectorizedArray< Number, width > exp(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation