📄 equation_systems.c
字号:
// $Id: equation_systems.C 2925 2008-07-10 13:34:46Z jwpeterson $// The libMesh Finite Element Library.// Copyright (C) 2002-2007 Benjamin S. Kirk, John W. Peterson // 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// System includes#include <sstream>// Local Includes#include "explicit_system.h"#include "fe_interface.h"#include "frequency_system.h"#include "linear_implicit_system.h"#include "mesh_refinement.h"#include "newmark_system.h"#include "nonlinear_implicit_system.h"#include "parallel.h"#include "transient_system.h"#include "dof_map.h"#include "mesh_base.h"#include "elem.h"#include "libmesh_logging.h"// Include the systems before this one to avoid// overlapping forward declarations.#include "equation_systems.h"// Forward Declarations// ------------------------------------------------------------// EquationSystems class implementationEquationSystems::EquationSystems (MeshBase& m, MeshData* mesh_data) : _mesh (m), _mesh_data (mesh_data){ // Set default parameters this->parameters.set<Real> ("linear solver tolerance") = TOLERANCE * TOLERANCE; this->parameters.set<unsigned int>("linear solver maximum iterations") = 5000;}EquationSystems::~EquationSystems (){ this->clear ();}void EquationSystems::clear (){ // Clear any additional parameters parameters.clear (); // clear the systems. We must delete them // since we newed them! while (!_systems.empty()) { system_iterator pos = _systems.begin(); System *sys = pos->second; delete sys; sys = NULL; _systems.erase (pos); }}void EquationSystems::init (){ const unsigned int n_sys = this->n_systems(); libmesh_assert (n_sys != 0); // Distribute the mesh if possible if (libMesh::n_processors() > 1) _mesh.delete_remote_elements(); // Tell all the \p DofObject entities how many systems // there are. { MeshBase::node_iterator node_it = _mesh.nodes_begin(); const MeshBase::node_iterator node_end = _mesh.nodes_end(); for ( ; node_it != node_end; ++node_it) (*node_it)->set_n_systems(n_sys); MeshBase::element_iterator elem_it = _mesh.elements_begin(); const MeshBase::element_iterator elem_end = _mesh.elements_end(); for ( ; elem_it != elem_end; ++elem_it) (*elem_it)->set_n_systems(n_sys); } for (unsigned int i=0; i != this->n_systems(); ++i) this->get_system(i).init();}void EquationSystems::reinit (){ libmesh_assert (this->n_systems() != 0); #ifdef DEBUG // Make sure all the \p DofObject entities know how many systems // there are. { // All the nodes MeshBase::node_iterator node_it = _mesh.nodes_begin(); const MeshBase::node_iterator node_end = _mesh.nodes_end(); for ( ; node_it != node_end; ++node_it) libmesh_assert((*node_it)->n_systems() == this->n_systems()); // All the elements MeshBase::element_iterator elem_it = _mesh.elements_begin(); const MeshBase::element_iterator elem_end = _mesh.elements_end(); for ( ; elem_it != elem_end; ++elem_it) libmesh_assert((*elem_it)->n_systems() == this->n_systems()); }#endif // Localize each system's vectors for (unsigned int i=0; i != this->n_systems(); ++i) this->get_system(i).re_update();#ifdef ENABLE_AMR bool dof_constraints_created = false; bool mesh_changed = false; // FIXME: For backwards compatibility, assume // refine_and_coarsen_elements or refine_uniformly have already // been called { for (unsigned int i=0; i != this->n_systems(); ++i) { System &sys = this->get_system(i); sys.get_dof_map().distribute_dofs(_mesh); sys.get_dof_map().create_dof_constraints(_mesh); sys.prolong_vectors(); } mesh_changed = true; dof_constraints_created = true; } // FIXME: Where should the user set maintain_level_one now?? // Don't override previous settings, for now MeshRefinement mesh_refine(_mesh); mesh_refine.face_level_mismatch_limit() = false; // Try to coarsen the mesh, then restrict each system's vectors // if necessary if (mesh_refine.coarsen_elements()) { for (unsigned int i=0; i != this->n_systems(); ++i) { System &sys = this->get_system(i); if (!dof_constraints_created) { sys.get_dof_map().distribute_dofs(_mesh); sys.get_dof_map().create_dof_constraints(_mesh); } sys.restrict_vectors(); } mesh_changed = true; dof_constraints_created = true; } // Once vectors are all restricted, we can delete // children of coarsened elements if (mesh_changed) this->get_mesh().contract(); // Try to refine the mesh, then prolong each system's vectors // if necessary if (mesh_refine.refine_elements()) { for (unsigned int i=0; i != this->n_systems(); ++i) { System &sys = this->get_system(i); if (!dof_constraints_created) { sys.get_dof_map().distribute_dofs(_mesh); sys.get_dof_map().create_dof_constraints(_mesh); } sys.prolong_vectors(); } mesh_changed = true; dof_constraints_created = true; } // If the mesh has changed, systems will need to create new dof // constraints and update their global solution vectors if (mesh_changed) { for (unsigned int i=0; i != this->n_systems(); ++i) this->get_system(i).reinit(); }#endif // #ifdef ENABLE_AMR}void EquationSystems::allgather (){ // A serial mesh means nothing needs to be done if (_mesh.is_serial()) return; const unsigned int n_sys = this->n_systems(); libmesh_assert (n_sys != 0); // Gather the mesh _mesh.allgather(); // Tell all the \p DofObject entities how many systems // there are. { MeshBase::node_iterator node_it = _mesh.nodes_begin(); const MeshBase::node_iterator node_end = _mesh.nodes_end(); for ( ; node_it != node_end; ++node_it) (*node_it)->set_n_systems(n_sys); MeshBase::element_iterator elem_it = _mesh.elements_begin(); const MeshBase::element_iterator elem_end = _mesh.elements_end(); for ( ; elem_it != elem_end; ++elem_it) (*elem_it)->set_n_systems(n_sys); } // And distribute each system's dofs for (unsigned int i=0; i != this->n_systems(); ++i) this->get_system(i).get_dof_map().distribute_dofs(_mesh);}void EquationSystems::update (){ START_LOG("update()","EquationSystems"); // Localize each system's vectors for (unsigned int i=0; i != this->n_systems(); ++i) this->get_system(i).update(); STOP_LOG("update()","EquationSystems");}System & EquationSystems::add_system (const std::string& sys_type, const std::string& name){ // Build a Newmark system if (sys_type == "Newmark") this->add_system<NewmarkSystem> (name); // Build an Explicit system else if ((sys_type == "Explicit")) this->add_system<ExplicitSystem> (name); // Build an Implicit system else if ((sys_type == "Implicit") || (sys_type == "Steady" )) this->add_system<ImplicitSystem> (name); // build a transient implicit linear system else if ((sys_type == "Transient") || (sys_type == "TransientImplicit") || (sys_type == "TransientLinearImplicit")) this->add_system<TransientLinearImplicitSystem> (name); // build a transient implicit nonlinear system else if (sys_type == "TransientNonlinearImplicit") this->add_system<TransientNonlinearImplicitSystem> (name); // build a transient explicit system else if (sys_type == "TransientExplicit") this->add_system<TransientExplicitSystem> (name); // build a linear implicit sytsem else if (sys_type == "LinearImplicit") this->add_system<LinearImplicitSystem> (name);#if defined(USE_COMPLEX_NUMBERS) // build a frequency system else if (sys_type == "Frequency") this->add_system<FrequencySystem> (name);#endif else { std::cerr << "ERROR: Unknown system type: " << sys_type << std::endl; libmesh_error(); } // Return a reference to the new system //return (*this)(name); return this->get_system(name);}void EquationSystems::delete_system (const std::string& name){ deprecated(); if (!_systems.count(name)) { std::cerr << "ERROR: no system named " << name << std::endl; libmesh_error(); } delete _systems[name]; _systems.erase (name);}void EquationSystems::solve (){ libmesh_assert (this->n_systems()); for (unsigned int i=0; i != this->n_systems(); ++i) this->get_system(i).solve();} void EquationSystems::build_variable_names (std::vector<std::string>& var_names) const{ libmesh_assert (this->n_systems()); var_names.resize (this->n_vars()); unsigned int var_num=0; const_system_iterator pos = _systems.begin(); const const_system_iterator end = _systems.end(); for (; pos != end; ++pos) for (unsigned int vn=0; vn<pos->second->n_vars(); vn++) var_names[var_num++] = pos->second->variable_name(vn); }void EquationSystems::build_solution_vector (std::vector<Number>&, const std::string&, const std::string&) const{ //TODO:[BSK] re-implement this from the method below libmesh_error();// // Get a reference to the named system// const System& system = this->get_system(system_name);// // Get the number associated with the variable_name we are passed// const unsigned short int variable_num = system.variable_number(variable_name);// // Get the dimension of the current mesh// const unsigned int dim = _mesh.mesh_dimension();// // If we're on processor 0, allocate enough memory to hold the solution.// // Since we're only looking at one variable, there will be one solution value// // for each node in the mesh.// if (_mesh.processor_id() == 0)// soln.resize(_mesh.n_nodes());// // Vector to hold the global solution from all processors// std::vector<Number> sys_soln; // // Update the global solution from all processors// system.update_global_solution (sys_soln, 0); // // Temporary vector to store the solution on an individual element.// std::vector<Number> elem_soln; // // The FE solution interpolated to the nodes// std::vector<Number> nodal_soln; // // The DOF indices for the element// std::vector<unsigned int> dof_indices; // // Determine the finite/infinite element type used in this system // const FEType& fe_type = system.variable_type(variable_num);// // Define iterators to iterate over all the elements of the mesh// const_active_elem_iterator it (_mesh.elements_begin());// const const_active_elem_iterator end(_mesh.elements_end());// // Loop over elements// for ( ; it != end; ++it)// {// // Convenient shortcut to the element pointer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -