From: Vladimir Yushutin Date: Tue, 9 Jul 2024 15:44:22 +0000 (-0400) Subject: step-62 and step-66 are omitted for now. X-Git-Tag: v9.6.0-rc1~75^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f6a869d2153d67e0b190f6f30ba559a0978bd972;p=dealii.git step-62 and step-66 are omitted for now. --- diff --git a/examples/step-60/parameters.prm b/examples/step-60/parameters.prm new file mode 100644 index 0000000000..e612757510 --- /dev/null +++ b/examples/step-60/parameters.prm @@ -0,0 +1,191 @@ +# Listing of Parameters +# --------------------- +subsection Distributed Lagrange<1,2> + set Coupling quadrature order = 3 + set Dirichlet boundary ids = 0, 1, 2, 3 + set Embedded configuration finite element degree = 1 + set Embedded space finite element degree = 1 + set Embedding space finite element degree = 1 + set Initial embedded space refinement = 8 + set Initial embedding space refinement = 4 + set Local refinements steps near embedded domain = 3 + set Use displacement in embedded interface = false + set Verbosity level = 10 + + + subsection Embedded configuration + # Sometimes it is convenient to use symbolic constants in the expression + # that describes the function, rather than having to use its numeric value + # everywhere the constant appears. These values can be defined using this + # parameter, in the form `var1=value1, var2=value2, ...'. + # + # A typical example would be to set this runtime parameter to + # `pi=3.1415926536' and then use `pi' in the expression of the actual + # formula. (That said, for convenience this class actually defines both + # `pi' and `Pi' by default, but you get the idea.) + set Function constants = R=.3, Cx=.4, Cy=.4 # default: + + # The formula that denotes the function you want to evaluate for + # particular values of the independent variables. This expression may + # contain any of the usual operations such as addition or multiplication, + # as well as all of the common functions such as `sin' or `cos'. In + # addition, it may contain expressions like `if(x>0, 1, -1)' where the + # expression evaluates to the second argument if the first argument is + # true, and to the third argument otherwise. For a full overview of + # possible expressions accepted see the documentation of the muparser + # library at http://muparser.beltoforion.de/. + # + # If the function you are describing represents a vector-valued function + # with multiple components, then separate the expressions for individual + # components by a semicolon. + set Function expression = R*cos(2*pi*x)+Cx; R*sin(2*pi*x)+Cy # default: 0 + + # The names of the variables as they will be used in the function, + # separated by commas. By default, the names of variables at which the + # function will be evaluated are `x' (in 1d), `x,y' (in 2d) or `x,y,z' (in + # 3d) for spatial coordinates and `t' for time. You can then use these + # variable names in your function expression and they will be replaced by + # the values of these variables at which the function is currently + # evaluated. However, you can also choose a different set of names for the + # independent variables at which to evaluate your function expression. For + # example, if you work in spherical coordinates, you may wish to set this + # input parameter to `r,phi,theta,t' and then use these variable names in + # your function expression. + set Variable names = x,y,t + end + + subsection Embedded value + # Sometimes it is convenient to use symbolic constants in the expression + # that describes the function, rather than having to use its numeric value + # everywhere the constant appears. These values can be defined using this + # parameter, in the form `var1=value1, var2=value2, ...'. + # + # A typical example would be to set this runtime parameter to + # `pi=3.1415926536' and then use `pi' in the expression of the actual + # formula. (That said, for convenience this class actually defines both + # `pi' and `Pi' by default, but you get the idea.) + set Function constants = + + # The formula that denotes the function you want to evaluate for + # particular values of the independent variables. This expression may + # contain any of the usual operations such as addition or multiplication, + # as well as all of the common functions such as `sin' or `cos'. In + # addition, it may contain expressions like `if(x>0, 1, -1)' where the + # expression evaluates to the second argument if the first argument is + # true, and to the third argument otherwise. For a full overview of + # possible expressions accepted see the documentation of the muparser + # library at http://muparser.beltoforion.de/. + # + # If the function you are describing represents a vector-valued function + # with multiple components, then separate the expressions for individual + # components by a semicolon. + set Function expression = 1 # default: 0 + + # The names of the variables as they will be used in the function, + # separated by commas. By default, the names of variables at which the + # function will be evaluated are `x' (in 1d), `x,y' (in 2d) or `x,y,z' (in + # 3d) for spatial coordinates and `t' for time. You can then use these + # variable names in your function expression and they will be replaced by + # the values of these variables at which the function is currently + # evaluated. However, you can also choose a different set of names for the + # independent variables at which to evaluate your function expression. For + # example, if you work in spherical coordinates, you may wish to set this + # input parameter to `r,phi,theta,t' and then use these variable names in + # your function expression. + set Variable names = x,y,t + end + + subsection Embedding Dirichlet boundary conditions + # Sometimes it is convenient to use symbolic constants in the expression + # that describes the function, rather than having to use its numeric value + # everywhere the constant appears. These values can be defined using this + # parameter, in the form `var1=value1, var2=value2, ...'. + # + # A typical example would be to set this runtime parameter to + # `pi=3.1415926536' and then use `pi' in the expression of the actual + # formula. (That said, for convenience this class actually defines both + # `pi' and `Pi' by default, but you get the idea.) + set Function constants = + + # The formula that denotes the function you want to evaluate for + # particular values of the independent variables. This expression may + # contain any of the usual operations such as addition or multiplication, + # as well as all of the common functions such as `sin' or `cos'. In + # addition, it may contain expressions like `if(x>0, 1, -1)' where the + # expression evaluates to the second argument if the first argument is + # true, and to the third argument otherwise. For a full overview of + # possible expressions accepted see the documentation of the muparser + # library at http://muparser.beltoforion.de/. + # + # If the function you are describing represents a vector-valued function + # with multiple components, then separate the expressions for individual + # components by a semicolon. + set Function expression = 0 + + # The names of the variables as they will be used in the function, + # separated by commas. By default, the names of variables at which the + # function will be evaluated are `x' (in 1d), `x,y' (in 2d) or `x,y,z' (in + # 3d) for spatial coordinates and `t' for time. You can then use these + # variable names in your function expression and they will be replaced by + # the values of these variables at which the function is currently + # evaluated. However, you can also choose a different set of names for the + # independent variables at which to evaluate your function expression. For + # example, if you work in spherical coordinates, you may wish to set this + # input parameter to `r,phi,theta,t' and then use these variable names in + # your function expression. + set Variable names = x,y,t + end + + subsection Embedding rhs function + # Sometimes it is convenient to use symbolic constants in the expression + # that describes the function, rather than having to use its numeric value + # everywhere the constant appears. These values can be defined using this + # parameter, in the form `var1=value1, var2=value2, ...'. + # + # A typical example would be to set this runtime parameter to + # `pi=3.1415926536' and then use `pi' in the expression of the actual + # formula. (That said, for convenience this class actually defines both + # `pi' and `Pi' by default, but you get the idea.) + set Function constants = + + # The formula that denotes the function you want to evaluate for + # particular values of the independent variables. This expression may + # contain any of the usual operations such as addition or multiplication, + # as well as all of the common functions such as `sin' or `cos'. In + # addition, it may contain expressions like `if(x>0, 1, -1)' where the + # expression evaluates to the second argument if the first argument is + # true, and to the third argument otherwise. For a full overview of + # possible expressions accepted see the documentation of the muparser + # library at http://muparser.beltoforion.de/. + # + # If the function you are describing represents a vector-valued function + # with multiple components, then separate the expressions for individual + # components by a semicolon. + set Function expression = 0 + + # The names of the variables as they will be used in the function, + # separated by commas. By default, the names of variables at which the + # function will be evaluated are `x' (in 1d), `x,y' (in 2d) or `x,y,z' (in + # 3d) for spatial coordinates and `t' for time. You can then use these + # variable names in your function expression and they will be replaced by + # the values of these variables at which the function is currently + # evaluated. However, you can also choose a different set of names for the + # independent variables at which to evaluate your function expression. For + # example, if you work in spherical coordinates, you may wish to set this + # input parameter to `r,phi,theta,t' and then use these variable names in + # your function expression. + set Variable names = x,y,t + end + + subsection Schur solver control + set Log frequency = 1 + set Log history = false + set Log result = true + set Max steps = 1000 # default: 100 + set Reduction = 1.e-12 # default: 1.e-2 + set Tolerance = 1.e-12 # default: 1.e-10 + end + +end + + diff --git a/tests/examples/step-60.diff b/tests/examples/step-60.diff new file mode 100644 index 0000000000..882b1b49bd --- /dev/null +++ b/tests/examples/step-60.diff @@ -0,0 +1,16 @@ +573c573 +< , monitor(std::cout, TimerOutput::summary, TimerOutput::cpu_and_wall_times) +--- +> , monitor(std::cout, TimerOutput::never, TimerOutput::cpu_and_wall_times) +1050c1050 +< deallog.depth_console(parameters.verbosity_level); +--- +> deallog.depth_console(1); +1092c1092 +< parameter_file = "parameters.prm"; +--- +> parameter_file = "../../../source/step-60/parameters.prm"; +1094c1094 +< ParameterAcceptor::initialize(parameter_file, "used_parameters.prm"); +--- +> ParameterAcceptor::initialize(parameter_file, "../../../source/step-60/used_parameters.prm"); diff --git a/tests/examples/step-60.with_umfpack=true.with_muparser=true.output b/tests/examples/step-60.with_umfpack=true.with_muparser=true.output new file mode 100644 index 0000000000..962573c912 --- /dev/null +++ b/tests/examples/step-60.with_umfpack=true.with_muparser=true.output @@ -0,0 +1,3 @@ +DEAL::Embedded dofs: 257 +DEAL::Embedding minimal diameter: 0.0110485, embedded maximal diameter: 0.00736292, ratio: 0.666416 +DEAL::Embedding dofs: 2429 \ No newline at end of file diff --git a/tests/examples/step-61.diff b/tests/examples/step-61.diff new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/examples/step-61.output b/tests/examples/step-61.output new file mode 100644 index 0000000000..848faa48fe --- /dev/null +++ b/tests/examples/step-61.output @@ -0,0 +1,7 @@ +Solving problem in 2 space dimensions. + Number of active cells: 1024 + Total number of cells: 1365 + Number of pressure degrees of freedom: 3136 +L2_error_pressure 0.0200372 +L2_error_vel: 0.0629738 +L2_error_flux: 0.0890227 diff --git a/tests/examples/step-63.diff b/tests/examples/step-63.diff new file mode 100644 index 0000000000..aa779b749b --- /dev/null +++ b/tests/examples/step-63.diff @@ -0,0 +1,23 @@ +27c27 +< +--- +> #include "../example_test.h" +1086c1086,1089 +< solver.solve(system_matrix, solution, system_rhs, preconditioner); +--- +> //solver.solve(system_matrix, solution, system_rhs, preconditioner); +> check_solver_within_range(std::cout, +> solver.solve(system_matrix, solution, system_rhs, preconditioner) +> , solver_control.last_step(), 2, 13); +1089,1091c1092,1094 +< std::cout << " converged in " << solver_control.last_step() +< << " iterations" +< << " in " << time.last_wall_time() << " seconds " << std::endl; +--- +> // std::cout << " converged in " << solver_control.last_step() +> // << " iterations" +> // << " in " << time.last_wall_time() << " seconds " << std::endl; +1235c1238 +< settings.get_parameters((argc > 1) ? (argv[1]) : ""); +--- +> settings.get_parameters((argc > 1) ? (argv[1]) : "../../../source/step-63/sor.prm"); diff --git a/tests/examples/step-63.output b/tests/examples/step-63.output new file mode 100644 index 0000000000..d6a52e3fce --- /dev/null +++ b/tests/examples/step-63.output @@ -0,0 +1,42 @@ + Cycle 0: + Number of active cells: 32 (2 levels) + Number of degrees of freedom: 48 + Solving with GMRES to tol 4.11776e-09... +Solver stopped within 2 - 13 iterations + + Cycle 1: + Number of active cells: 128 (3 levels) + Number of degrees of freedom: 160 + Solving with GMRES to tol 4.35567e-09... +Solver stopped within 2 - 13 iterations + + Cycle 2: + Number of active cells: 512 (4 levels) + Number of degrees of freedom: 576 + Solving with GMRES to tol 3.73965e-09... +Solver stopped within 2 - 13 iterations + + Cycle 3: + Number of active cells: 2048 (5 levels) + Number of degrees of freedom: 2176 + Solving with GMRES to tol 2.96763e-09... +Solver stopped within 2 - 13 iterations + + Cycle 4: + Number of active cells: 8192 (6 levels) + Number of degrees of freedom: 8448 + Solving with GMRES to tol 2.33887e-09... +Solver stopped within 2 - 13 iterations + + Cycle 5: + Number of active cells: 32768 (7 levels) + Number of degrees of freedom: 33280 + Solving with GMRES to tol 1.93553e-09... +Solver stopped within 2 - 13 iterations + + Cycle 6: + Number of active cells: 131072 (8 levels) + Number of degrees of freedom: 132096 + Solving with GMRES to tol 1.83347e-09... +Solver stopped within 2 - 13 iterations + diff --git a/tests/examples/step-64.diff b/tests/examples/step-64.diff new file mode 100644 index 0000000000..9c1a6c50e0 --- /dev/null +++ b/tests/examples/step-64.diff @@ -0,0 +1,16 @@ +22c22 +< +--- +> #include "../example_test.h" +519,522c519,524 +< cg.solve(*system_matrix_dev, solution_dev, system_rhs_dev, preconditioner); +< +< pcout << " Solved in " << solver_control.last_step() << " iterations." +< << std::endl; +--- +> //cg.solve(*system_matrix_dev, solution_dev, system_rhs_dev, preconditioner); +> check_solver_within_range(pcout,cg.solve(*system_matrix_dev, solution_dev, system_rhs_dev, preconditioner), +> solver_control.last_step(), +> 26, 228); +> // pcout << " Solved in " << solver_control.last_step() << " iterations." +> // << std::endl; diff --git a/tests/examples/step-64.mpirun=2.with_p4est=true.output b/tests/examples/step-64.mpirun=2.with_p4est=true.output new file mode 100644 index 0000000000..61efb2a3a0 --- /dev/null +++ b/tests/examples/step-64.mpirun=2.with_p4est=true.output @@ -0,0 +1,24 @@ +Cycle 0 + Number of active cells: 8 + Number of degrees of freedom: 343 +Solver stopped within 26 - 228 iterations + solution norm: 0.0205439 + +Cycle 1 + Number of active cells: 64 + Number of degrees of freedom: 2197 +Solver stopped within 26 - 228 iterations + solution norm: 0.0205269 + +Cycle 2 + Number of active cells: 512 + Number of degrees of freedom: 15625 +Solver stopped within 26 - 228 iterations + solution norm: 0.0205261 + +Cycle 3 + Number of active cells: 4096 + Number of degrees of freedom: 117649 +Solver stopped within 26 - 228 iterations + solution norm: 0.0205261 + diff --git a/tests/examples/step-65.diff b/tests/examples/step-65.diff index f6c959d5d9..110ca952b1 100644 --- a/tests/examples/step-65.diff +++ b/tests/examples/step-65.diff @@ -1,16 +1,34 @@ 23a24 > #include +25c26 +< +--- +> #include "../example_test.h" 268c269 < triangulation.refine_global(9 - 2 * dim); --- > triangulation.refine_global(2); -619d619 +436c437,441 +< solver.solve(system_matrix, solution, system_rhs, preconditioner); +--- +> //solver.solve(system_matrix, solution, system_rhs, preconditioner); +> check_solver_within_range(std::cout, +> solver.solve(system_matrix, solution, system_rhs, preconditioner), +> solver_control.last_step(), +> 137, 228); +439,440c444,445 +< std::cout << " Number of solver iterations: " +< << solver_control.last_step() << std::endl; +--- +> // std::cout << " Number of solver iterations: " +> // << solver_control.last_step() << std::endl; +619d623 < timer.print_summary(); -644,645d643 +644,645d647 < std::cout << " Memory consumption cache: " < << 1e-6 * mapping.memory_consumption() << " MB" << std::endl; -651,652d648 +651,652d652 < < timer.print_summary(); -660a657 +660a661 > dealii::MultithreadInfo::set_thread_limit(2); diff --git a/tests/examples/step-65.output b/tests/examples/step-65.output index 6cf62063d8..aa82107571 100644 --- a/tests/examples/step-65.output +++ b/tests/examples/step-65.output @@ -3,7 +3,7 @@ Number of active cells: 832 Number of degrees of freedom: 22981 - Number of solver iterations: 138 +Solver stopped within 137 - 228 iterations L2 error vs exact solution: 1.39878e-06 H1 error vs exact solution: 5.16394e-05 Max cell-wise error estimate: 0.0217657 @@ -11,7 +11,7 @@ Number of active cells: 832 Number of degrees of freedom: 22981 - Number of solver iterations: 138 +Solver stopped within 137 - 228 iterations L2 error vs exact solution: 1.39878e-06 H1 error vs exact solution: 5.16394e-05 Max cell-wise error estimate: 0.0217657 diff --git a/tests/examples/step-67.diff b/tests/examples/step-67.diff index 3d57c3ab52..de0e6dfdc7 100644 --- a/tests/examples/step-67.diff +++ b/tests/examples/step-67.diff @@ -1,26 +1,26 @@ -75c75 +74c74 < constexpr unsigned int n_global_refinements = 3; --- > constexpr unsigned int n_global_refinements = 2; -82c82 +81c81 < constexpr double final_time = testcase == 0 ? 10 : 2.0; --- > constexpr double final_time = testcase == 0 ? 5 : 2.0; -2171,2173c2171 +2169,2171c2169 < const std::string filename = < "solution_" + Utilities::int_to_string(result_number, 3) + ".vtu"; < data_out.write_vtu_in_parallel(filename, MPI_COMM_WORLD); --- > (void)result_number; -2196,2198d2193 +2194,2196d2191 < const unsigned int n_vect_number = VectorizedArray::size(); < const unsigned int n_vect_bits = 8 * sizeof(Number) * n_vect_number; < -2202,2206d2196 +2200,2204d2194 < pcout << "Vectorization over " << n_vect_number << ' ' < << (std::is_same_v ? "doubles" : "floats") << " = " < << n_vect_bits << " bits (" < << Utilities::System::get_current_vectorization_level() << ')' < << std::endl; -2284d2273 +2282d2271 < timer.print_wall_time_statistics(MPI_COMM_WORLD); diff --git a/tests/examples/step-68.diff b/tests/examples/step-68.diff new file mode 100644 index 0000000000..08d5685d35 --- /dev/null +++ b/tests/examples/step-68.diff @@ -0,0 +1,8 @@ +635c635 +< DiscreteTime discrete_time(0, par.final_time, par.time_step); +--- +> DiscreteTime discrete_time(0, 0.04, par.time_step); +723c723 +< prm_file = "parameters.prm"; +--- +> prm_file = "../../../source/step-68/parameters.prm"; diff --git a/tests/examples/step-68.with_p4est=true.output b/tests/examples/step-68.with_p4est=true.output new file mode 100644 index 0000000000..cee49689d7 --- /dev/null +++ b/tests/examples/step-68.with_p4est=true.output @@ -0,0 +1,13 @@ +Number of particles inserted: 384 +Repartitioning triangulation after particle generation +Writing particle output file: analytical-particles-0 +Writing particle output file: analytical-particles-10 +Writing particle output file: analytical-particles-20 +Number of particles inserted: 384 +Repartitioning triangulation after particle generation +Writing particle output file: interpolated-particles-0 +Writing background field file: background-0 +Writing particle output file: interpolated-particles-10 +Writing background field file: background-10 +Writing particle output file: interpolated-particles-20 +Writing background field file: background-20 diff --git a/tests/examples/step-69.diff b/tests/examples/step-69.diff new file mode 100644 index 0000000000..5bd3094442 --- /dev/null +++ b/tests/examples/step-69.diff @@ -0,0 +1,18 @@ +2400c2400 +< t_final = 4.; +--- +> t_final = 4.0; +2469c2469 +< ParameterAcceptor::initialize("step-69.prm"); +--- +> ParameterAcceptor::initialize("../../../source/step-69/step-69.prm"); +2572c2572 +< while (t < t_final) +--- +> while (t < 0.01) +2616,2617c2616,2617 +< computing_timer.print_summary(); +< pcout << timer_output.str() << std::endl; +--- +> // computing_timer.print_summary(); +> // pcout << timer_output.str() << std::endl; diff --git a/tests/examples/step-69.with_mpi=true.with_p4est=true.output b/tests/examples/step-69.with_mpi=true.with_p4est=true.output new file mode 100644 index 0000000000..cfa158f281 --- /dev/null +++ b/tests/examples/step-69.with_mpi=true.with_p4est=true.output @@ -0,0 +1,205 @@ +Reading parameters and allocating objects... done + + #################################################### + ######### ######### + ######### create triangulation ######### + ######### ######### + ######### ######### + #################################################### + +Number of active cells: 36864 + + #################################################### + ######### ######### + ######### compute offline data ######### + ######### ######### + ######### ######### + #################################################### + +Number of degrees of freedom: 37376 + + #################################################### + ######### ######### + ######### set up time step ######### + ######### ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### interpolate initial values ######### + ######### ######### + ######### ######### + #################################################### + +MainLoop::interpolate_initial_values(t = 0) +MainLoop::output(t = 0) + + #################################################### + ######### ######### + ######### enter main loop ######### + ######### ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### Cycle 000001 (0.0%) ######### + ######### at time t = 0.00000000 ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### Cycle 000002 (0.0%) ######### + ######### at time t = 0.00047162 ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### Cycle 000003 (0.0%) ######### + ######### at time t = 0.00095766 ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### Cycle 000004 (0.0%) ######### + ######### at time t = 0.00144812 ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### Cycle 000005 (0.0%) ######### + ######### at time t = 0.00194250 ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### Cycle 000006 (0.1%) ######### + ######### at time t = 0.00244039 ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### Cycle 000007 (0.1%) ######### + ######### at time t = 0.00294140 ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### Cycle 000008 (0.1%) ######### + ######### at time t = 0.00344520 ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### Cycle 000009 (0.1%) ######### + ######### at time t = 0.00395144 ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### Cycle 000010 (0.1%) ######### + ######### at time t = 0.00445967 ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### Cycle 000011 (0.1%) ######### + ######### at time t = 0.00496964 ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### Cycle 000012 (0.1%) ######### + ######### at time t = 0.00548105 ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### Cycle 000013 (0.1%) ######### + ######### at time t = 0.00599373 ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### Cycle 000014 (0.2%) ######### + ######### at time t = 0.00650751 ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### Cycle 000015 (0.2%) ######### + ######### at time t = 0.00702215 ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### Cycle 000016 (0.2%) ######### + ######### at time t = 0.00753756 ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### Cycle 000017 (0.2%) ######### + ######### at time t = 0.00805362 ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### Cycle 000018 (0.2%) ######### + ######### at time t = 0.00856990 ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### Cycle 000019 (0.2%) ######### + ######### at time t = 0.00908599 ######### + ######### ######### + #################################################### + + + #################################################### + ######### ######### + ######### Cycle 000020 (0.2%) ######### + ######### at time t = 0.00960148 ######### + ######### ######### + #################################################### +