⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ex7.c

📁 一个用来实现偏微分方程中网格的计算库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: ex7.C 2837 2008-05-08 17:23:37Z roystgnr $ *//* The Next Great Finite Element Library. *//* Copyright (C) 2003  Benjamin S. Kirk *//* This library is free software; you can redistribute it and/or *//* modify it under the terms of the GNU Lesser General Public *//* License as published by the Free Software Foundation; either *//* version 2.1 of the License, or (at your option) any later version. *//* This library is distributed in the hope that it will be useful, *//* but WITHOUT ANY WARRANTY; without even the implied warranty of *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *//* Lesser General Public License for more details. *//* You should have received a copy of the GNU Lesser General Public *//* License along with this library; if not, write to the Free Software *//* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */ // <h1>Example 7 - Introduction to Complex Numbers and the "FrequencySystem"</h1> // // This is the seventh example program.  It builds on // the previous example programs, introduces complex // numbers and the FrequencySystem class to solve a  // simple Helmholtz equation grad(p)*grad(p)+(omega/c)^2*p=0, // for multiple frequencies rather efficiently. // // The FrequencySystem class offers two solution styles, // namely to solve large systems, or to solve // moderately-sized systems fast, for multiple frequencies. // The latter approach is implemented here. // // This example uses an L--shaped mesh and nodal boundary data // given in the files lshape.un and lshape_data.unv // // For this example the library has to be compiled with // complex numbers enabled.  // C++ include files that we need#include <iostream>#include <algorithm>#include <stdio.h>// Basic include files needed for overall functionality.#include "libmesh.h"#include "libmesh_logging.h"#include "mesh.h"#include "mesh_generation.h"#include "gmv_io.h"#include "equation_systems.h"#include "elem.h"// Include FrequencySystem.  Compared to GeneralSystem,// this class offers added functionality for the solution of // frequency-dependent systems.#include "frequency_system.h"// Define the Finite Element object.#include "fe.h"// Define Gauss quadrature rules.#include "quadrature_gauss.h"// Define useful datatypes for finite element// matrix and vector components.#include "dense_matrix.h"#include "dense_vector.h"// Define matrix and vector data types for the global // equation system.  These are base classes,// from which specific implementations, like// the PETSc or LASPACK implementations, are derived.#include "sparse_matrix.h"#include "numeric_vector.h"// Define the DofMap, which handles degree of freedom// indexing.#include "dof_map.h"// Defines the MeshData class, which allows you to store// data about the mesh when reading in files, etc.#include "mesh_data.h"// This problem is only defined on complex-valued fields, for// which libMesh must be configured with Number == complex.#ifdef USE_COMPLEX_NUMBERS// Function prototype.  This is the function that will assemble// the mass, damping and stiffness matrices.  It will <i>not</i>// form an overall system matrix ready for solution.void assemble_helmholtz(EquationSystems& es,                        const std::string& system_name);// Function prototype.  This is the function that will combine// the previously-assembled mass, damping and stiffness matrices// to the overall matrix, which then renders ready for solution.void add_M_C_K_helmholtz(EquationSystems& es,                         const std::string& system_name);#endif// Begin the main program.  Note that this example only// works correctly if complex numbers have been enabled// in the library.  In order to link against the complex// PETSc libraries, you must have built PETSc with the same// C++ compiler that you used to build libMesh.  This is// so that the name mangling will be the same for the// routines in both libraries.int main (int argc, char** argv){  // Initialize libraries, like in example 2.  LibMeshInit init (argc, argv);    // This example is designed for complex numbers.   #ifndef USE_COMPLEX_NUMBERS  if (libMesh::processor_id() == 0)    std::cerr << "ERROR: This example is intended for " << std::endl              << " use with complex numbers." << std::endl;  return 0;#else    // Check for proper usage.  if (argc < 3)    {      if (libMesh::processor_id() == 0)        std::cerr << "Usage: " << argv[0] << " -f [frequency]"                  << std::endl;            libmesh_error();    }    // Tell the user what we are doing.  else     {      std::cout << "Running " << argv[0];            for (int i=1; i<argc; i++)        std::cout << " " << argv[i];            std::cout << std::endl << std::endl;    }    // For now, restrict to dim=2, though this  // may easily be changed, see example 4  const unsigned int dim = 2;    // Get the frequency from argv[2] as a <i>float</i>,  // currently, solve for 1/3rd, 2/3rd and 1/1th of the given frequency  const Real frequency_in = atof(argv[2]);  const unsigned int n_frequencies = 3;            // Create a dim-dimensional mesh.  Mesh mesh (dim);  // Create a corresponding MeshData  // and activate it. For more information on this object  // cf. example 12.  MeshData mesh_data(mesh);  mesh_data.activate();  // Read the mesh file. Here the file lshape.unv contains  // an L--shaped domain in .unv format.  mesh.read("lshape.unv", &mesh_data);  // Print information about the mesh to the screen.  mesh.print_info();      // The load on the boundary of the domain is stored in  // the .unv formated mesh data file lshape_data.unv.  // At this, the data is given as complex valued normal  // velocities.  mesh_data.read("lshape_data.unv");  // Print information about the mesh to the screen.  mesh_data.print_info();  // Create an equation systems object, which now handles  // a frequency system, as opposed to previous examples.  // Also pass a MeshData pointer so the data can be   // accessed in the matrix and rhs assembly.  EquationSystems equation_systems (mesh, &mesh_data);    // Create a FrequencySystem named "Helmholtz" & store a  // reference to it.  FrequencySystem & f_system =          equation_systems.add_system<FrequencySystem> ("Helmholtz");    // Add the variable "p" to "Helmholtz".  "p"  // will be approximated using second-order approximation.  f_system.add_variable("p", SECOND);    // Tell the frequency system about the two user-provided  // functions.  In other circumstances, at least the  // solve function has to be attached.  f_system.attach_assemble_function (assemble_helmholtz);  f_system.attach_solve_function    (add_M_C_K_helmholtz);    // To enable the fast solution scheme, additional  // <i>global</i> matrices and one global vector, all appropriately sized,  // have to be added.  The system object takes care of the  // appropriate size, but the user should better fill explicitly  // the sparsity structure of the overall matrix, so that the  // fast matrix addition method can be used, as will be shown later.  f_system.add_matrix ("stiffness");  f_system.add_matrix ("damping");  f_system.add_matrix ("mass");  f_system.add_vector ("rhs");    // Communicates the frequencies to the system.  Note that  // the frequency system stores the frequencies as parameters  // in the equation systems object, so that our assemble and solve  // functions may directly access them.  // Will solve for 1/3rd, 2/3rd and 1/1th of the given frequency  f_system.set_frequencies_by_steps (frequency_in/n_frequencies,                                     frequency_in,                                     n_frequencies);    // Use the parameters of the equation systems object to  // tell the frequency system about the wave velocity and fluid  // density.  The frequency system provides default values, but  // these may be overridden, as shown here.  equation_systems.parameters.set<Real> ("wave speed") = 1.;  equation_systems.parameters.set<Real> ("rho")        = 1.;    // Initialize the data structures for the equation system.  <i>Always</i>  // prior to this, the frequencies have to be communicated to the system.  equation_systems.init ();    // Prints information about the system to the screen.  equation_systems.print_info ();  for (unsigned int n=0; n < n_frequencies; n++)    {      // Solve the system "Helmholtz" for the n-th frequency.        // Since we attached an assemble() function to the system,      // the mass, damping and stiffness contributions will only      // be assembled once.  Then, the system is solved for the      // given frequencies.  Note that solve() may also solve       // the system only for specific frequencies.      f_system.solve (n,n);            // After solving the system, write the solution      // to a GMV-formatted plot file, for every frequency.        // Now this is nice ;-) : we have the <i>identical</i>       // interface to the mesh write method as in the real-only       // case, but we output the real and imaginary       // part, and the magnitude, where the variable       // "p" is prepended with "r_", "i_", and "a_",       // respectively.      char buf[14];      sprintf (buf, "out%04d.gmv", n);      GMVIO(mesh).write_equation_systems (buf,                                          equation_systems);    }    // Alternatively, the whole EquationSystems object can be  // written to disk.  By default, the additional vectors are also  // saved.  equation_systems.write ("eqn_sys.dat", libMeshEnums::WRITE);    // All done.    return 0;#endif }#ifdef USE_COMPLEX_NUMBERS// Here we define the matrix assembly routine for// the Helmholtz system.  This function will be// called to form the stiffness matrix and right-hand side.void assemble_helmholtz(EquationSystems& es,                        const std::string& system_name){      // It is a good idea to make sure we are assembling  // the proper system.  libmesh_assert (system_name == "Helmholtz");    // Get a constant reference to the mesh object.  const MeshBase& mesh = es.get_mesh();    // The dimension that we are in  const unsigned int dim = mesh.mesh_dimension();    // Get a reference to our system, as before  FrequencySystem & f_system =    es.get_system<FrequencySystem> (system_name);    // A const reference to the DofMap object for this system.  The DofMap  // object handles the index translation from node and element numbers  // to degree of freedom numbers.  const DofMap& dof_map = f_system.get_dof_map();    // Get a constant reference to the Finite Element type  // for the first (and only) variable in the system.  const FEType& fe_type = dof_map.variable_type(0);  // For the admittance boundary condition,  // get the fluid density  const Real rho = es.parameters.get<Real>("rho");    // In here, we will add the element matrices to the  // <i>additional</i> matrices "stiffness_mass", "damping",  // and the additional vector "rhs", not to the members   // "matrix" and "rhs".  Therefore, get writable  // references to them  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");  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -