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

📄 ex10.c

📁 一个用来实现偏微分方程中网格的计算库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: ex10.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 10 - Solving a Transient System with Adaptive Mesh Refinement</h1>  //   // This example shows how a simple, linear transient  // system can be solved in parallel.  The system is simple  // scalar convection-diffusion with a specified external  // velocity.  The initial condition is given, and the  // solution is advanced in time with a standard Crank-Nicolson  // time-stepping strategy.  //  // Also, we use this example to demonstrate writing out and reading  // in of solutions. We do 25 time steps, then save the solution  // and do another 25 time steps starting from the saved solution. // C++ include files that we need#include <iostream>#include <algorithm>#include <cmath>// Basic include file needed for the mesh functionality.#include "libmesh.h"#include "mesh.h"#include "mesh_refinement.h"#include "gmv_io.h"#include "equation_systems.h"#include "fe.h"#include "quadrature_gauss.h"#include "dof_map.h"#include "sparse_matrix.h"#include "numeric_vector.h"#include "dense_matrix.h"#include "dense_vector.h"#include "getpot.h"// Some (older) compilers do not offer full stream // functionality, \p OStringStream works around this.// Check example 9 for details.#include "o_string_stream.h"// This example will solve a linear transient system,// so we need to include the \p TransientLinearImplicitSystem definition.#include "transient_system.h"#include "linear_implicit_system.h"#include "vector_value.h"// To refine the mesh we need an \p ErrorEstimator// object to figure out which elements to refine.#include "error_vector.h"#include "kelly_error_estimator.h"// The definition of a geometric element#include "elem.h"// Function prototype.  This function will assemble the system// matrix and right-hand-side at each time step.  Note that// since the system is linear we technically do not need to// assmeble the matrix at each time step, but we will anyway.// In subsequent examples we will employ adaptive mesh refinement,// and with a changing mesh it will be necessary to rebuild the// system matrix.void assemble_cd (EquationSystems& es,                  const std::string& system_name);// Function prototype.  This function will initialize the system.// Initialization functions are optional for systems.  They allow// you to specify the initial values of the solution.  If an// initialization function is not provided then the default (0)// solution is provided.void init_cd (EquationSystems& es,              const std::string& system_name);// Exact solution function prototype.  This gives the exact// solution as a function of space and time.  In this case the// initial condition will be taken as the exact solution at time 0,// as will the Dirichlet boundary conditions at time t.Real exact_solution (const Real x,                     const Real y,                     const Real t);Number exact_value (const Point& p,                    const Parameters& parameters,                    const std::string&,                    const std::string&){  return exact_solution(p(0), p(1), parameters.get<Real> ("time"));}// Begin the main program.  Note that the first// statement in the program throws an error if// you are in complex number mode, since this// example is only intended to work with real// numbers.int main (int argc, char** argv){  // Initialize libMesh.  LibMeshInit init (argc, argv);#ifndef ENABLE_AMR  if (libMesh::processor_id() == 0)    std::cerr << "ERROR: This example requires libMesh to be\n"              << "compiled with AMR support!"              << std::endl;  return 0;#else  // Brief message to the user regarding the program name  // and command line arguments.  // Use commandline parameter to specify if we are to  // read in an initial solution or generate it ourself  std::cout << "Usage:\n"    <<"\t " << argv[0] << " -init_timestep 0\n"    << "OR\n"    <<"\t " << argv[0] << " -read_solution -init_timestep 26\n"    << std::endl;  std::cout << "Running: " << argv[0];  for (int i=1; i<argc; i++)    std::cout << " " << argv[i];  std::cout << std::endl << std::endl;  // Create a GetPot object to parse the command line  GetPot command_line (argc, argv);  // This boolean value is obtained from the command line, it is true  // if the flag "-read_solution" is present, false otherwise.  // It indicates whether we are going to read in  // the mesh and solution files "saved_mesh.xda" and "saved_solution.xda"  // or whether we are going to start from scratch by just reading  // "mesh.xda"  const bool read_solution   = command_line.search("-read_solution");  // This value is also obtained from the commandline and it specifies the  // initial value for the t_step looping variable. We must  // distinguish between the two cases here, whether we read in the   // solution or we started from scratch, so that we do not overwrite the  // gmv output files.  unsigned int init_timestep = 0;    // Search the command line for the "init_timestep" flag and if it is  // present, set init_timestep accordingly.  if(command_line.search("-init_timestep"))    init_timestep = command_line.next(0);  else    {      if (libMesh::processor_id() == 0)        std::cerr << "ERROR: Initial timestep not specified\n" << std::endl;      // This handy function will print the file name, line number,      // and then abort.  Currrently the library does not use C++      // exception handling.      libmesh_error();    }  // This value is also obtained from the command line, and specifies  // the number of time steps to take.  unsigned int n_timesteps = 0;  // Again do a search on the command line for the argument  if(command_line.search("-n_timesteps"))    n_timesteps = command_line.next(0);  else    {      std::cout << "ERROR: Number of timesteps not specified\n" << std::endl;      libmesh_error();    }  // Create a two-dimensional mesh.  Mesh mesh (2);  // Create an equation systems object.  EquationSystems equation_systems (mesh);  MeshRefinement mesh_refinement (mesh);  // First we process the case where we do not read in the solution  if(!read_solution)    {      // Read the mesh from file.      mesh.read ("mesh.xda");      // Uniformly refine the mesh 5 times      if(!read_solution)        mesh_refinement.uniformly_refine (5);      // Print information about the mesh to the screen.      mesh.print_info();                  // Declare the system and its variables.      // Begin by creating a transient system      // named "Convection-Diffusion".      TransientLinearImplicitSystem & system =         equation_systems.add_system<TransientLinearImplicitSystem>         ("Convection-Diffusion");      // Adds the variable "u" to "Convection-Diffusion".  "u"      // will be approximated using first-order approximation.      system.add_variable ("u", FIRST);      // Give the system a pointer to the matrix assembly      // and initialization functions.      system.attach_assemble_function (assemble_cd);      system.attach_init_function (init_cd);      // Initialize the data structures for the equation system.      equation_systems.init ();    }  // Otherwise we read in the solution and mesh  else     {      // Read in the mesh stored in "saved_mesh.xda"      mesh.read("saved_mesh.xda");      // Print information about the mesh to the screen.      mesh.print_info();      // Read in the solution stored in "saved_solution.xda"      equation_systems.read("saved_solution.xda", libMeshEnums::READ);      // Get a reference to the system so that we can call update() on it      TransientLinearImplicitSystem & system =         equation_systems.get_system<TransientLinearImplicitSystem>         ("Convection-Diffusion");      // We need to call update to put system in a consistent state      // with the solution that was read in      system.update();      // Attach the same matrix assembly function as above. Note, we do not      // have to attach an init() function since we are initializing the      // system by reading in "saved_solution.xda"      system.attach_assemble_function (assemble_cd);    }  // Prints information about the system to the screen.  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)    // Write out the initial condition    GMVIO(mesh).write_equation_systems ("out.gmv.000",                                        equation_systems);  else    // Write out the solution that was read in    GMVIO(mesh).write_equation_systems ("solution_read_in.gmv",                                        equation_systems);  // The Convection-Diffusion system requires that we specify  // the flow velocity.  We will specify it as a RealVectorValue  // data type and then use the Parameters object to pass it to  // the assemble function.  equation_systems.parameters.set<RealVectorValue>("velocity") =     RealVectorValue (0.8, 0.8);      // Solve the system "Convection-Diffusion".  This will be done by  // looping over the specified time interval and calling the  // \p solve() member at each time step.  This will assemble the  // system and call the linear solver.  const Real dt = 0.025;  Real time     = init_timestep*dt;    // We do 25 timesteps both before and after writing out the  // intermediate solution  for(unsigned int t_step=init_timestep;                    t_step<(init_timestep+n_timesteps);                    t_step++)    {      // Increment the time counter, set the time and the      // time step size as parameters in the EquationSystem.      time += dt;      equation_systems.parameters.set<Real> ("time") = time;      equation_systems.parameters.set<Real> ("dt")   = dt;      // A pretty update message      std::cout << " Solving time step ";            // As already seen in example 9, use a work-around      // for missing stream functionality (of older compilers).      // Add a set of scope braces to enforce data locality.      {        OStringStream out;        OSSInt(out,2,t_step);        out << ", time=";        OSSRealzeroleft(out,6,3,time);        out <<  "...";        std::cout << out.str() << std::endl;      }            // At this point we need to update the old      // solution vector.  The old solution vector      // will be the current solution vector from the      // previous time step.  We will do this by extracting the      // system from the \p EquationSystems object and using      // vector assignment.  Since only \p TransientLinearImplicitSystems      // (and systems derived from them) contain old solutions      // we need to specify the system type when we ask for it.      TransientLinearImplicitSystem &  system =        equation_systems.get_system<TransientLinearImplicitSystem>("Convection-Diffusion");      *system.old_local_solution = *system.current_local_solution;            // The number of refinement steps per time step.      const unsigned int max_r_steps = 2;            // A refinement loop.      for (unsigned int r_step=0; r_step<max_r_steps; r_step++)        {

⌨️ 快捷键说明

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