📄 ex9.c
字号:
/* $Id: ex9.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 9 - Solving a Transient Linear System in Parallel</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.// C++ include files that we need#include <iostream>#include <algorithm>#include <math.h>// 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"// Some (older) compilers do not offer full stream // functionality, OStringStream works around this.#include "o_string_stream.h"// This example will solve a linear transient system,// so we need to include the \p TransientLinearImplicitSystem definition.#include "linear_implicit_system.h"#include "transient_system.h"#include "vector_value.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"));}// We can now begin the main program. Note that this// example will fail if you are using complex numbers// since it was designed to be run only 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 // Create a two-dimensional mesh. Mesh mesh (2); // Read the mesh from file. This is the coarse mesh that will be used // in example 10 to demonstrate adaptive mesh refinement. Here we will // simply read it in and uniformly refine it 5 times before we compute // with it. mesh.read ("../ex10/mesh.xda"); // Create a MeshRefinement object to handle refinement of our mesh. // This class handles all the details of mesh refinement and coarsening. MeshRefinement mesh_refinement (mesh); // Uniformly refine the mesh 5 times. This is the // first time we use the mesh refinement capabilities // of the library. mesh_refinement.uniformly_refine (5); // Print information about the mesh to the screen. mesh.print_info(); // Create an equation systems object. EquationSystems equation_systems (mesh); // Add a transient system to the EquationSystems // object 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 (); // Prints information about the system to the screen. equation_systems.print_info(); // Write out the initial conditions. GMVIO(mesh).write_equation_systems ("out_000.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 // solve() member at each time step. This will assemble the // system and call the linear solver. const Real dt = 0.025; Real time = 0.; for (unsigned int t_step = 0; t_step < 50; t_step++) { // Incremenet 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 "; // Since some compilers fail to offer full stream // functionality, libMesh offers a string stream // to work around this. Note that for other compilers, // this is just a set of preprocessor macros and therefore // should cost nothing (compared to a hand-coded string stream). // We use additional curly braces here simply 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 TransientSystems // (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; // Assemble & solve the linear system equation_systems.get_system("Convection-Diffusion").solve(); // Output evey 10 timesteps to file. if ( (t_step+1)%10 == 0) { OStringStream file_name; file_name << "out_"; OSSRealzeroright(file_name,3,0,t_step+1); file_name << ".gmv"; GMVIO(mesh).write_equation_systems (file_name.str(), equation_systems); } }#endif // #ifdef ENABLE_AMR // All done. return 0;}// We now define the function which provides the// initialization routines for the "Convection-Diffusion"// system. This handles things like setting initial// conditions and boundary conditions.void init_cd (EquationSystems& es, const std::string& system_name){ // It is a good idea to make sure we are initializing
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -