📄 ex10.php
字号:
system by reading in "saved_solution.xda"</div><div class ="fragment"><pre> system.attach_assemble_function (assemble_cd); } </pre></div><div class = "comment">Prints information about the system to the screen.</div><div class ="fragment"><pre> equation_systems.print_info(); equation_systems.parameters.set<unsigned int> ("linear solver maximum iterations") = 250; equation_systems.parameters.set<Real> ("linear solver tolerance") = TOLERANCE; if(!read_solution)</pre></div><div class = "comment">Write out the initial condition</div><div class ="fragment"><pre> GMVIO(mesh).write_equation_systems ("out.gmv.000", equation_systems); else</pre></div><div class = "comment">Write out the solution that was read in</div><div class ="fragment"><pre> GMVIO(mesh).write_equation_systems ("solution_read_in.gmv", equation_systems); </pre></div><div class = "comment">The Convection-Diffusion system requires that we specifythe flow velocity. We will specify it as a RealVectorValuedata type and then use the Parameters object to pass it tothe assemble function.</div><div class ="fragment"><pre> equation_systems.parameters.set<RealVectorValue>("velocity") = RealVectorValue (0.8, 0.8); </pre></div><div class = "comment">Solve the system "Convection-Diffusion". This will be done bylooping over the specified time interval and calling the\p solve() member at each time step. This will assemble thesystem and call the linear solver.</div><div class ="fragment"><pre> const Real dt = 0.025; Real time = init_timestep*dt; </pre></div><div class = "comment">We do 25 timesteps both before and after writing out theintermediate solution</div><div class ="fragment"><pre> for(unsigned int t_step=init_timestep; t_step<(init_timestep+n_timesteps); t_step++) {</pre></div><div class = "comment">Increment the time counter, set the time and thetime step size as parameters in the EquationSystem.</div><div class ="fragment"><pre> time += dt; equation_systems.parameters.set<Real> ("time") = time; equation_systems.parameters.set<Real> ("dt") = dt; </pre></div><div class = "comment">A pretty update message</div><div class ="fragment"><pre> std::cout << " Solving time step "; </pre></div><div class = "comment">As already seen in example 9, use a work-aroundfor missing stream functionality (of older compilers).Add a set of scope braces to enforce data locality.</div><div class ="fragment"><pre> { OStringStream out; OSSInt(out,2,t_step); out << ", time="; OSSRealzeroleft(out,6,3,time); out << "..."; std::cout << out.str() << std::endl; } </pre></div><div class = "comment">At this point we need to update the oldsolution vector. The old solution vectorwill be the current solution vector from theprevious time step. We will do this by extracting thesystem from the \p EquationSystems object and usingvector assignment. Since only \p TransientLinearImplicitSystems(and systems derived from them) contain old solutionswe need to specify the system type when we ask for it.</div><div class ="fragment"><pre> TransientLinearImplicitSystem & system = equation_systems.get_system<TransientLinearImplicitSystem>("Convection-Diffusion"); *system.old_local_solution = *system.current_local_solution; </pre></div><div class = "comment">The number of refinement steps per time step.</div><div class ="fragment"><pre> const unsigned int max_r_steps = 2; </pre></div><div class = "comment">A refinement loop.</div><div class ="fragment"><pre> for (unsigned int r_step=0; r_step<max_r_steps; r_step++) {</pre></div><div class = "comment">Assemble & solve the linear system</div><div class ="fragment"><pre> system.solve(); </pre></div><div class = "comment">Possibly refine the mesh</div><div class ="fragment"><pre> if (r_step+1 != max_r_steps) { std::cout << " Refining the mesh..." << std::endl; </pre></div><div class = "comment">The \p ErrorVector is a particular \p StatisticsVectorfor computing error information on a finite element mesh.</div><div class ="fragment"><pre> ErrorVector error; </pre></div><div class = "comment">The \p ErrorEstimator class interrogates a finite elementsolution and assigns to each element a positive error value.This value is used for deciding which elements to refineand which to coarsen.ErrorEstimator* error_estimator = new KellyErrorEstimator;</div><div class ="fragment"><pre> KellyErrorEstimator error_estimator; </pre></div><div class = "comment">Compute the error for each active element using the provided\p flux_jump indicator. Note in general you will need toprovide an error estimator specifically designed for yourapplication.</div><div class ="fragment"><pre> error_estimator.estimate_error (system, error); </pre></div><div class = "comment">This takes the error in \p error and decides which elementswill be coarsened or refined. Any element within 20% of themaximum error on any element will be refined, and anyelement within 7% of the minimum error on any element mightbe coarsened. Note that the elements flagged for refinementwill be refined, but those flagged for coarsening _might_ becoarsened.</div><div class ="fragment"><pre> mesh_refinement.refine_fraction() = 0.80; mesh_refinement.coarsen_fraction() = 0.07; mesh_refinement.max_h_level() = 5; mesh_refinement.flag_elements_by_error_fraction (error); </pre></div><div class = "comment">This call actually refines and coarsens the flaggedelements.</div><div class ="fragment"><pre> mesh_refinement.refine_and_coarsen_elements(); </pre></div><div class = "comment">This call reinitializes the \p EquationSystems object forthe newly refined mesh. One of the steps in thereinitialization is projecting the \p solution,\p old_solution, etc... vectors from the old mesh tothe current one.</div><div class ="fragment"><pre> equation_systems.reinit (); } } </pre></div><div class = "comment">Output evey 10 timesteps to file.</div><div class ="fragment"><pre> if ( (t_step+1)%10 == 0) { OStringStream file_name; file_name << "out.gmv."; OSSRealzeroright(file_name,3,0,t_step+1); GMVIO(mesh).write_equation_systems (file_name.str(), equation_systems); } } if(!read_solution) { mesh.write("saved_mesh.xda"); equation_systems.write("saved_solution.xda", libMeshEnums::WRITE); } } #endif // #ifndef ENABLE_AMR </pre></div><div class = "comment">All done. </div><div class ="fragment"><pre> return libMesh::close (); } </pre></div><div class = "comment">Here we define the initialization routine for theConvection-Diffusion system. This routine isresponsible for applying the initial conditions tothe system.</div><div class ="fragment"><pre> void init_cd (EquationSystems& es, const std::string& system_name) {</pre></div><div class = "comment">It is a good idea to make sure we are initializingthe proper system.</div><div class ="fragment"><pre> assert (system_name == "Convection-Diffusion"); </pre></div><div class = "comment">Get a reference to the Convection-Diffusion system object.</div><div class ="fragment"><pre> TransientLinearImplicitSystem & system = es.get_system<TransientLinearImplicitSystem>("Convection-Diffusion"); </pre></div><div class = "comment">Project initial conditions at time 0</div><div class ="fragment"><pre> es.parameters.set<Real> ("time") = 0; system.project_solution(exact_value, NULL, es.parameters); } </pre></div><div class = "comment">This function defines the assembly routine whichwill be called at each time step. It is responsiblefor computing the proper matrix entries for theelement stiffness matrices and right-hand sides.</div><div class ="fragment"><pre> void assemble_cd (EquationSystems& es, const std::string& system_name) { #ifdef ENABLE_AMR</pre></div><div class = "comment">It is a good idea to make sure we are assemblingthe proper system.</div><div class ="fragment"><pre> assert (system_name == "Convection-Diffusion"); </pre></div><div class = "comment">Get a constant reference to the mesh object.</div><div class ="fragment"><pre> const Mesh& mesh = es.get_mesh(); </pre></div><div class = "comment">The dimension that we are running</div><div class ="fragment"><pre> const unsigned int dim = mesh.mesh_dimension(); </pre></div><div class = "comment">Get a reference to the Convection-Diffusion system object.</div><div class ="fragment"><pre> TransientLinearImplicitSystem & system = es.get_system<TransientLinearImplicitSystem> ("Convection-Diffusion"); </pre></div><div class = "comment">Get the Finite Element type for the first (and only) variable in the system.</div><div class ="fragment"><pre> FEType fe_type = system.variable_type(0); </pre></div><div class = "comment">Build a Finite Element object of the specified type. Since the\p FEBase::build() member dynamically creates memory we willstore the object as an \p AutoPtr<FEBase>. This can be thoughtof as a pointer that will clean up after itself.</div><div class ="fragment"><pre> AutoPtr<FEBase> fe (FEBase::build(dim, fe_type)); AutoPtr<FEBase> fe_face (FEBase::build(dim, fe_type)); </pre></div><div class = "comment">A Gauss quadrature rule for numerical integration.Let the \p FEType object decide what order rule is appropriate.</div><div class ="fragment"><pre> QGauss qrule (dim, fe_type.default_quadrature_order()); QGauss qface (dim-1, fe_type.default_quadrature_order()); </pre></div><div class = "comment">Tell the finite element object to use our quadrature rule.</div><div class ="fragment"><pre> fe->attach_quadrature_rule (&qrule); fe_face->attach_quadrature_rule (&qface); </pre></div><div class = "comment">Here we define some references to cell-specific data thatwill be used to assemble the linear system. We will startwith the element Jacobian * quadrature weight at each integration point.</div><div class ="fragment"><pre> const std::vector<Real>& JxW = fe->get_JxW(); const std::vector<Real>& JxW_face = fe_face->get_JxW(); </pre></div><div class = "comment">The element shape functions evaluated at the quadrature points.</div><div class ="fragment"><pre> const std::vector<std::vector<Real> >& phi = fe->get_phi(); const std::vector<std::vector<Real> >& psi = fe_face->get_phi();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -