📄 ex8.php
字号:
</pre></div><div class = "comment">Initialize the data structures for the equation system.</div><div class ="fragment"><pre> equation_systems.init(); </pre></div><div class = "comment">Prints information about the system to the screen.</div><div class ="fragment"><pre> equation_systems.print_info(); } </pre></div><div class = "comment">A file to store the results at certain nodes.</div><div class ="fragment"><pre> std::ofstream res_out("pressure_node.res"); </pre></div><div class = "comment">get the dof_numbers for the nodes thatshould be monitored.</div><div class ="fragment"><pre> const unsigned int res_node_no = result_node; const Node& res_node = mesh.node(res_node_no-1); unsigned int dof_no = res_node.dof_number(0,0,0); </pre></div><div class = "comment">Use a handy reference to this system</div><div class ="fragment"><pre> NewmarkSystem& t_system = equation_systems.get_system<NewmarkSystem> ("Wave"); </pre></div><div class = "comment">Assemble the time independent system matrices and rhs.This function will also compute the effective system matrixK~=K+a_0*M+a_1*C and apply user specified initialconditions. </div><div class ="fragment"><pre> t_system.assemble(); </pre></div><div class = "comment">Now solve for each time step.For convenience, use a local buffer of the current time. But once this time is updated,also update the \p EquationSystems parameterStart with t_time = 0 and write a short headerto the nodal result file</div><div class ="fragment"><pre> Real t_time = 0.; res_out << "# pressure at node " << res_node_no << "\n" << "# time\tpressure\n" << t_time << "\t" << 0 << std::endl; for (unsigned int time_step=0; time_step<n_time_steps; time_step++) {</pre></div><div class = "comment">Update the time. Both here and in the\p EquationSystems object</div><div class ="fragment"><pre> t_time += delta_t; equation_systems.parameters.set<Real>("time") = t_time; </pre></div><div class = "comment">Update the rhs.</div><div class ="fragment"><pre> t_system.update_rhs(); </pre></div><div class = "comment">Impose essential boundary conditions.Not that since the matrix is only assembled once,the penalty parameter should be added to the matrixonly in the first time step. The appliedboundary conditions may be time-dependent and hencethe rhs vector is considered in each time step. </div><div class ="fragment"><pre> if (time_step == 0) {</pre></div><div class = "comment">The local function \p fill_dirichlet_bc()may also set Dirichlet boundary conditions for thematrix. When you set the flag as shown below,the flag will return true. If you want it to returnfalse, simply do not set it.</div><div class ="fragment"><pre> equation_systems.parameters.set<bool>("Newmark set BC for Matrix") = true; fill_dirichlet_bc(equation_systems, "Wave"); </pre></div><div class = "comment">unset the flag, so that it returns false</div><div class ="fragment"><pre> equation_systems.parameters.set<bool>("Newmark set BC for Matrix") = false; } else fill_dirichlet_bc(equation_systems, "Wave"); </pre></div><div class = "comment">Solve the system "Wave".</div><div class ="fragment"><pre> t_system.solve(); </pre></div><div class = "comment">After solving the system, write the solutionto a GMV-formatted plot file.Do only for a few time steps.</div><div class ="fragment"><pre> if (time_step == 30 || time_step == 60 || time_step == 90 || time_step == 120 ) { char buf[14]; sprintf (buf, "out.%03d.gmv", time_step); GMVIO(mesh).write_equation_systems (buf, equation_systems); } </pre></div><div class = "comment">Update the p, v and a.</div><div class ="fragment"><pre> t_system.update_u_v_a(); </pre></div><div class = "comment">dof_no may not be local in parallel runs, so we may need aglobal displacement vector</div><div class ="fragment"><pre> NumericVector<Number> &displacement = t_system.get_vector("displacement"); std::vector<Number> global_displacement(displacement.size()); displacement.localize(global_displacement); </pre></div><div class = "comment">Write nodal results to file. The results can thenbe viewed with e.g. gnuplot (run gnuplot and type'plot "pressure_node.res" with lines' in the command line)</div><div class ="fragment"><pre> res_out << t_time << "\t" << global_displacement[dof_no] << std::endl; } } </pre></div><div class = "comment">All done. </div><div class ="fragment"><pre> return libMesh::close (); } </pre></div><div class = "comment">This function assembles the system matrix and right-hand-sidefor our wave equation.</div><div class ="fragment"><pre> void assemble_wave(EquationSystems& es, const std::string& system_name) { </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 == "Wave"); </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">Copy the speed of sound and fluid densityto a local variable.</div><div class ="fragment"><pre> const Real speed = es.parameters.get<Real>("speed"); const Real rho = es.parameters.get<Real>("fluid density"); </pre></div><div class = "comment">Get a reference to our system, as before.</div><div class ="fragment"><pre> NewmarkSystem & t_system = es.get_system<NewmarkSystem> (system_name); </pre></div><div class = "comment">Get a constant reference to the Finite Element typefor the first (and only) variable in the system.</div><div class ="fragment"><pre> FEType fe_type = t_system.get_dof_map().variable_type(0); </pre></div><div class = "comment">In here, we will add the element matrices to the@e additional matrices "stiffness_mass" and "damping"and the additional vector "force", not to the members "matrix" and "rhs". Therefore, get writablereferences to them.</div><div class ="fragment"><pre> SparseMatrix<Number>& stiffness = t_system.get_matrix("stiffness"); SparseMatrix<Number>& damping = t_system.get_matrix("damping"); SparseMatrix<Number>& mass = t_system.get_matrix("mass"); NumericVector<Number>& force = t_system.get_vector("force"); </pre></div><div class = "comment">Some solver packages (PETSc) are especially picky aboutallocating sparsity structure and truly assigning valuesto this structure. Namely, matrix additions, as performedlater, exhibit acceptable performance only for identicalsparsity structures. Therefore, explicitly zero thevalues in the collective matrix, so that matrix additionsencounter identical sparsity structures.</div><div class ="fragment"><pre> SparseMatrix<Number>& matrix = *t_system.matrix; DenseMatrix<Number> zero_matrix; </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)); </pre></div><div class = "comment">A 2nd order Gauss quadrature rule for numerical integration.</div><div class ="fragment"><pre> QGauss qrule (dim, SECOND); </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); </pre></div><div class = "comment">The element Jacobian * quadrature weight at each integration point. </div><div class ="fragment"><pre> const std::vector<Real>& JxW = fe->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(); </pre></div><div class = "comment">The element shape function gradients evaluated at the quadraturepoints.</div><div class ="fragment"><pre> const std::vector<std::vector<RealGradient> >& dphi = fe->get_dphi(); </pre></div><div class = "comment">A reference to the \p DofMap object for this system. The \p DofMapobject handles the index translation from node and element numbersto degree of freedom numbers.</div><div class ="fragment"><pre> const DofMap& dof_map = t_system.get_dof_map(); </pre></div><div class = "comment">The element mass, damping and stiffness matricesand the element contribution to the rhs.</div><div class ="fragment"><pre> DenseMatrix<Number> Ke, Ce, Me; DenseVector<Number> Fe; </pre></div><div class = "comment">This vector will hold the degree of freedom indices forthe element. These define where in the global systemthe element degrees of freedom get mapped.</div><div class ="fragment"><pre> std::vector<unsigned int> dof_indices; </pre></div><div class = "comment">Now we will loop over all the elements in the mesh.We will compute the element matrix and right-hand-sidecontribution.const_elem_iterator el (mesh.elements_begin());const const_elem_iterator end_el (mesh.elements_end());<br><br></div><div class ="fragment"><pre> MeshBase::const_element_iterator el = mesh.elements_begin(); const MeshBase::const_element_iterator end_el = mesh.elements_end(); for ( ; el != end_el; ++el) {</pre></div>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -