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