📄 ex7.php
字号:
</div><div class ="fragment"><pre> STOP_LOG("elem init","assemble_helmholtz"); </pre></div><div class = "comment">Now loop over the quadrature points. This handlesthe numeric integration.</div><div class ="fragment"><pre> START_LOG("stiffness & mass","assemble_helmholtz"); for (unsigned int qp=0; qp<qrule.n_points(); qp++) {</pre></div><div class = "comment">Now we will build the element matrix. This involvesa double loop to integrate the test funcions (i) againstthe trial functions (j). Note the braces on the rhsof Ke(i,j): these are quite necessary to finally computeReal*(Point*Point) = Real, and not something else...</div><div class ="fragment"><pre> for (unsigned int i=0; i<phi.size(); i++) for (unsigned int j=0; j<phi.size(); j++) { Ke(i,j) += JxW[qp]*(dphi[i][qp]*dphi[j][qp]); Me(i,j) += JxW[qp]*(phi[i][qp]*phi[j][qp]); } } STOP_LOG("stiffness & mass","assemble_helmholtz"); </pre></div><div class = "comment">Now compute the contribution to the element matrix(due to mixed boundary conditions) if the currentelement lies on the boundary. <br><br>The following loops over the sides of the element.If the element has no neighbor on a side then thatside MUST live on a boundary of the domain. <br><br></div><div class ="fragment"><pre> for (unsigned int side=0; side<elem->n_sides(); side++) if (elem->neighbor(side) == NULL) { START_LOG("damping","assemble_helmholtz"); </pre></div><div class = "comment">Declare a special finite element object forboundary integration.</div><div class ="fragment"><pre> AutoPtr<FEBase> fe_face (FEBase::build(dim, fe_type)); </pre></div><div class = "comment">Boundary integration requires one quadraure rule,with dimensionality one less than the dimensionalityof the element.</div><div class ="fragment"><pre> QGauss qface(dim-1, SECOND); </pre></div><div class = "comment">Tell the finte element object to use ourquadrature rule.</div><div class ="fragment"><pre> fe_face->attach_quadrature_rule (&qface); </pre></div><div class = "comment">The value of the shape functions at the quadraturepoints.</div><div class ="fragment"><pre> const std::vector<std::vector<Real> >& phi_face = fe_face->get_phi(); </pre></div><div class = "comment">The Jacobian// Quadrature Weight at the quadraturepoints on the face.</div><div class ="fragment"><pre> const std::vector<Real>& JxW_face = fe_face->get_JxW(); </pre></div><div class = "comment">Compute the shape function values on the elementface.</div><div class ="fragment"><pre> fe_face->reinit(elem, side); </pre></div><div class = "comment">For the Robin BCs consider a normal admittance an=1at some parts of the bounfdary</div><div class ="fragment"><pre> const Real an_value = 1.; </pre></div><div class = "comment">Loop over the face quadrature points for integration.</div><div class ="fragment"><pre> for (unsigned int qp=0; qp<qface.n_points(); qp++) { </pre></div><div class = "comment">Element matrix contributrion due to precribedadmittance boundary conditions.</div><div class ="fragment"><pre> for (unsigned int i=0; i<phi_face.size(); i++) for (unsigned int j=0; j<phi_face.size(); j++) Ce(i,j) += rho*an_value*JxW_face[qp]*phi_face[i][qp]*phi_face[j][qp]; } STOP_LOG("damping","assemble_helmholtz"); } </pre></div><div class = "comment">Finally, simply add the contributions to the additionalmatrices and vector.</div><div class ="fragment"><pre> stiffness.add_matrix (Ke, dof_indices); damping.add_matrix (Ce, dof_indices); mass.add_matrix (Me, dof_indices); </pre></div><div class = "comment">For the overall matrix, explicitly zero the entries wherewe added values in the other ones, so that we have identical sparsity footprints.</div><div class ="fragment"><pre> matrix.add_matrix(zero_matrix, dof_indices); } // loop el </pre></div><div class = "comment">It now remains to compute the rhs. Here, we simplyget the normal velocities values on the boundary from themesh data.</div><div class ="fragment"><pre> { START_LOG("rhs","assemble_helmholtz"); </pre></div><div class = "comment">get a reference to the mesh data.</div><div class ="fragment"><pre> const MeshData& mesh_data = es.get_mesh_data(); </pre></div><div class = "comment">We will now loop over all nodes. In case nodal data for a certain node is available in the MeshData, we simplyadopt the corresponding value for the rhs vector.Note that normal data was given in the mesh data file,i.e. one value per node</div><div class ="fragment"><pre> assert(mesh_data.n_val_per_node() == 1); MeshBase::const_node_iterator node_it = mesh.nodes_begin(); const MeshBase::const_node_iterator node_end = mesh.nodes_end(); for ( ; node_it != node_end; ++node_it) {</pre></div><div class = "comment">the current node pointer</div><div class ="fragment"><pre> const Node* node = *node_it; </pre></div><div class = "comment">check if the mesh data has data for the current nodeand do for all components</div><div class ="fragment"><pre> if (mesh_data.has_data(node)) for (unsigned int comp=0; comp<node->n_comp(0,0); comp++) {</pre></div><div class = "comment">the dof number</div><div class ="fragment"><pre> unsigned int dn = node->dof_number(0,0,comp); </pre></div><div class = "comment">set the nodal value</div><div class ="fragment"><pre> freq_indep_rhs.set(dn, mesh_data.get_data(node)[0]); } } STOP_LOG("rhs","assemble_helmholtz"); } </pre></div><div class = "comment">All done!</div><div class ="fragment"><pre> #endif } </pre></div><div class = "comment">We now define the function which will combinethe previously-assembled mass, stiffness, anddamping matrices into a single system matrix.</div><div class ="fragment"><pre> void add_M_C_K_helmholtz(EquationSystems& es, const std::string& system_name) { #ifdef USE_COMPLEX_NUMBERS START_LOG("init phase","add_M_C_K_helmholtz"); </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 == "Helmholtz"); </pre></div><div class = "comment">Get a reference to our system, as before</div><div class ="fragment"><pre> FrequencySystem & f_system = es.get_system<FrequencySystem> (system_name); </pre></div><div class = "comment">Get the frequency, fluid density, and speed of soundfor which we should currently solve</div><div class ="fragment"><pre> const Real frequency = es.parameters.get<Real> ("current frequency"); const Real rho = es.parameters.get<Real> ("rho"); const Real speed = es.parameters.get<Real> ("wave speed"); </pre></div><div class = "comment">Compute angular frequency omega and wave number k</div><div class ="fragment"><pre> const Real omega = 2.0*libMesh::pi*frequency; const Real k = omega / speed; </pre></div><div class = "comment">Get writable references to the overall matrix and vector, where the frequency-dependent system is to be collected</div><div class ="fragment"><pre> SparseMatrix<Number>& matrix = *f_system.matrix; NumericVector<Number>& rhs = *f_system.rhs; </pre></div><div class = "comment">Get writable references to the frequency-independent matricesand rhs, though we only need to extract values. This write accessis necessary, since solver packages have to close the data structure before they can extract values for computation.</div><div class ="fragment"><pre> SparseMatrix<Number>& stiffness = f_system.get_matrix("stiffness"); SparseMatrix<Number>& damping = f_system.get_matrix("damping"); SparseMatrix<Number>& mass = f_system.get_matrix("mass"); NumericVector<Number>& freq_indep_rhs = f_system.get_vector("rhs"); </pre></div><div class = "comment">form the scaling values for the coming matrix and vector axpy's</div><div class ="fragment"><pre> const Number scale_stiffness ( 1., 0. ); const Number scale_damping ( 0., omega); const Number scale_mass (-k*k, 0. ); const Number scale_rhs ( 0., -(rho*omega)); </pre></div><div class = "comment">Now simply add the matrices together, store the resultin matrix and rhs. Clear them first.</div><div class ="fragment"><pre> matrix.close(); matrix.zero (); rhs.close(); rhs.zero (); </pre></div>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -