System Class Reference

#include <system.h>

Inheritance diagram for System:

List of all members.

Classes

class  BuildProjectionList
class  ProjectSolution
class  ProjectVector
class  Variable

Public Types

typedef System sys_type
typedef std::map< std::string,
NumericVector< Number >
* >::iterator 
vectors_iterator
typedef std::map< std::string,
NumericVector< Number >
* >::const_iterator 
const_vectors_iterator

Public Member Functions

virtual ~System ()
sys_typesystem ()
virtual void clear ()
void init ()
virtual void reinit ()
virtual void update ()
virtual void assemble ()
virtual void assemble_qoi ()
virtual void solve ()=0
virtual void adjoint_solve ()=0
virtual bool compare (const System &other_system, const Real threshold, const bool verbose) const
const std::string & name () const
virtual std::string system_type () const
void project_solution (Number fptr(const Point &p, const Parameters &parameters, const std::string &sys_name, const std::string &unknown_name), Gradient gptr(const Point &p, const Parameters &parameters, const std::string &sys_name, const std::string &unknown_name), Parameters &parameters) const
void project_vector (Number fptr(const Point &p, const Parameters &parameters, const std::string &sys_name, const std::string &unknown_name), Gradient gptr(const Point &p, const Parameters &parameters, const std::string &sys_name, const std::string &unknown_name), Parameters &parameters, NumericVector< Number > &new_vector) const
unsigned int number () const
void update_global_solution (std::vector< Number > &global_soln) const
void update_global_solution (std::vector< Number > &global_soln, const unsigned int dest_proc) const
const MeshBaseget_mesh () const
MeshBaseget_mesh ()
const DofMapget_dof_map () const
DofMapget_dof_map ()
const EquationSystemsget_equation_systems () const
EquationSystemsget_equation_systems ()
bool active () const
void activate ()
void deactivate ()
vectors_iterator vectors_begin ()
const_vectors_iterator vectors_begin () const
vectors_iterator vectors_end ()
const_vectors_iterator vectors_end () const
NumericVector< Number > & add_vector (const std::string &vec_name, const bool projections=true)
bool & project_solution_on_reinit (void)
bool have_vector (const std::string &vec_name) const
const NumericVector< Number > & get_vector (const std::string &vec_name) const
NumericVector< Number > & get_vector (const std::string &vec_name)
NumericVector< Number > & get_adjoint_solution ()
unsigned int n_vectors () const
unsigned int n_vars () const
unsigned int n_dofs () const
unsigned int n_active_dofs () const
unsigned int n_constrained_dofs () const
unsigned int n_local_dofs () const
unsigned int add_variable (const std::string &var, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=NULL)
unsigned int add_variable (const std::string &var, const Order order=FIRST, const FEFamily=LAGRANGE, const std::set< subdomain_id_type > *const active_subdomains=NULL)
const Variablevariable (unsigned int var) const
bool has_variable (const std::string &var) const
const std::string & variable_name (const unsigned int i) const
unsigned short int variable_number (const std::string &var) const
const FETypevariable_type (const unsigned int i) const
const FETypevariable_type (const std::string &var) const
Real calculate_norm (NumericVector< Number > &v, unsigned int var=0, FEMNormType norm_type=L2) const
Real calculate_norm (NumericVector< Number > &v, const SystemNorm &norm) const
void read_header (Xdr &io, const std::string &version, const bool read_header=true, const bool read_additional_data=true, const bool read_legacy_format=false)
void read_legacy_data (Xdr &io, const bool read_additional_data=true)
void read_serialized_data (Xdr &io, const bool read_additional_data=true)
void read_parallel_data (Xdr &io, const bool read_additional_data)
void write_header (Xdr &io, const std::string &version, const bool write_additional_data) const
void write_serialized_data (Xdr &io, const bool write_additional_data=true) const
void write_parallel_data (Xdr &io, const bool write_additional_data) const
std::string get_info () const
void attach_init_function (void fptr(EquationSystems &es, const std::string &name))
void attach_assemble_function (void fptr(EquationSystems &es, const std::string &name))
void attach_constraint_function (void fptr(EquationSystems &es, const std::string &name))
void attach_QOI_function (void fptr(EquationSystems &es, const std::string &name))
virtual void user_initialization ()
virtual void user_assembly ()
virtual void user_constrain ()
virtual void user_QOI ()
virtual void re_update ()
virtual void restrict_vectors ()
virtual void prolong_vectors ()
Number current_solution (const unsigned int global_dof_number) const
void local_dof_indices (const unsigned int var, std::set< unsigned int > &var_indices) const
void zero_variable (NumericVector< Number > &v, unsigned int var_num) const

Static Public Member Functions

static std::string get_info ()
static void print_info ()
static unsigned int n_objects ()

Public Attributes

bool assemble_before_solve
AutoPtr< NumericVector< Number > > solution
AutoPtr< NumericVector< Number > > current_local_solution

Protected Types

typedef std::map< std::string,
std::pair< unsigned int,
unsigned int > > 
Counts

Protected Member Functions

 System (EquationSystems &es, const std::string &name, const unsigned int number)
virtual void init_data ()
void project_vector (NumericVector< Number > &) const
void project_vector (const NumericVector< Number > &, NumericVector< Number > &) const
void increment_constructor_count (const std::string &name)
void increment_destructor_count (const std::string &name)

Static Protected Attributes

static Counts _counts
static Threads::atomic
< unsigned int > 
_n_objects
static Threads::spin_mutex _mutex

Private Member Functions

Real discrete_var_norm (NumericVector< Number > &v, unsigned int var, FEMNormType norm_type) const
template<typename iterator_type >
unsigned int read_serialized_blocked_dof_objects (const unsigned int var, const unsigned int n_objects, const iterator_type begin, const iterator_type end, Xdr &io, NumericVector< Number > &vec) const
void read_serialized_vector (Xdr &io, NumericVector< Number > &vec)
template<typename iterator_type >
unsigned int write_serialized_blocked_dof_objects (const NumericVector< Number > &vec, const unsigned int var, const unsigned int n_objects, const iterator_type begin, const iterator_type end, Xdr &io) const
void write_serialized_vector (Xdr &io, const NumericVector< Number > &vec) const

Private Attributes

void(* _init_system )(EquationSystems &es, const std::string &name)
void(* _assemble_system )(EquationSystems &es, const std::string &name)
void(* _constrain_system )(EquationSystems &es, const std::string &name)
void(* _qoi_evaluate_system )(EquationSystems &es, const std::string &name)
AutoPtr< DofMap_dof_map
EquationSystems_equation_systems
MeshBase_mesh
const std::string _sys_name
const unsigned int _sys_number
std::vector< System::Variable_variables
std::map< std::string,
unsigned short int > 
_variable_numbers
bool _active
std::map< std::string,
NumericVector< Number > * > 
_vectors
std::map< std::string, bool > _vector_projections
bool _solution_projection
bool _can_add_vectors
bool _additional_data_written


Detailed Description

This is the base class for classes which contain information related to any physical process that might be simulated. Such information may range from the actual solution values to algorithmic flags that may be used to control the numerical methods employed. In general, use an EqnSystems<T_sys> object to handle one or more of the children of this class. Note that templating EqnSystems relaxes the use of virtual members.

Author:
Benjamin S. Kirk, 2003-2004.

Definition at line 65 of file system.h.


Member Typedef Documentation

typedef std::map<std::string, NumericVector<Number>* >::const_iterator System::const_vectors_iterator

Definition at line 264 of file system.h.

typedef std::map<std::string, std::pair<unsigned int, unsigned int> > ReferenceCounter::Counts [protected, inherited]

Data structure to log the information. The log is identified by the class name.

Definition at line 105 of file reference_counter.h.

typedef std::map<std::string, NumericVector<Number>* >::iterator System::vectors_iterator

Vector iterator typedefs.

Definition at line 263 of file system.h.


Constructor & Destructor Documentation

System::System ( EquationSystems es,
const std::string &  name,
const unsigned int  number 
) [protected]

Constructor. Optionally initializes required data structures. Protected so that this base class cannot be explicitly instantiated.

Definition at line 46 of file system.C.

00048                                            :
00049 
00050   assemble_before_solve    (true),
00051   solution                 (NumericVector<Number>::build()),
00052   current_local_solution   (NumericVector<Number>::build()),
00053   _init_system             (NULL),
00054   _assemble_system         (NULL),
00055   _constrain_system        (NULL),
00056   _dof_map                 (new DofMap(number)),
00057   _equation_systems        (es),
00058   _mesh                    (es.get_mesh()),
00059   _sys_name                (name),
00060   _sys_number              (number),
00061   _active                  (true),
00062   _solution_projection     (true),
00063   _can_add_vectors         (true),
00064   _additional_data_written (false)
00065 {
00066 }

System::~System (  )  [virtual]

Destructor.

Definition at line 70 of file system.C.

References _assemble_system, _init_system, clear(), and libMesh::closed().

00071 {
00072   // Null-out the function pointers.  Since this
00073   // class is getting destructed it is pointless,
00074   // but a good habit.
00075   _init_system = _assemble_system = NULL;
00076 
00077   // Clear data
00078   this->clear ();
00079 
00080   libmesh_assert (!libMesh::closed());
00081 }


Member Function Documentation

void System::activate (  )  [inline]

Activates the system. Only active systems are solved.

Definition at line 1036 of file system.h.

References _active.

01037 {
01038   _active = true;
01039 }

bool System::active (  )  const [inline]

Returns:
true if the system is active, false otherwise. An active system will be solved.

Definition at line 1028 of file system.h.

References _active.

01029 {
01030   return _active;  
01031 }

unsigned int System::add_variable ( const std::string &  var,
const Order  order = FIRST,
const FEFamily  family = LAGRANGE,
const std::set< subdomain_id_type > *const   active_subdomains = NULL 
)

Adds the variable var to the list of variables for this system. Same as before, but assumes LAGRANGE as default value for FEType.family.

Definition at line 617 of file system.C.

References add_variable().

00621 {
00622   return this->add_variable(var, 
00623                             FEType(order, family), 
00624                             active_subdomains);
00625 }

unsigned int System::add_variable ( const std::string &  var,
const FEType type,
const std::set< subdomain_id_type > *const   active_subdomains = NULL 
)

Adds the variable var to the list of variables for this system. Returns the index number for the new variable.

Definition at line 578 of file system.C.

References _dof_map, _variable_numbers, _variables, n_vars(), number(), variable_name(), and variable_type().

Referenced by add_variable(), ErrorVector::plot_error(), and read_header().

00581 {  
00582   // Make sure the variable isn't there already
00583   // or if it is, that it's the type we want
00584   for (unsigned int v=0; v<this->n_vars(); v++)
00585     if (this->variable_name(v) == var)
00586       {
00587         if (this->variable_type(v) == type)
00588           return _variables[v].number();
00589 
00590         std::cerr << "ERROR: incompatible variable "
00591                   << var
00592                   << " has already been added for this system!"
00593                   << std::endl;
00594         libmesh_error();
00595       }
00596 
00597   const unsigned int curr_n_vars = this->n_vars();                                              
00598 
00599   // Add the variable to the list
00600   _variables.push_back((active_subdomains == NULL) ?
00601                        Variable(var, curr_n_vars, type) :
00602                        Variable(var, curr_n_vars, type, *active_subdomains));
00603 
00604   libmesh_assert ((curr_n_vars+1) == this->n_vars());
00605 
00606   _variable_numbers[var] = curr_n_vars;
00607 
00608   // Add the variable to the _dof_map
00609   _dof_map->add_variable (_variables.back());
00610 
00611   // Return the number of the new variable
00612   return curr_n_vars;
00613 }

NumericVector< Number > & System::add_vector ( const std::string &  vec_name,
const bool  projections = true 
)

Adds the additional vector vec_name to this system. Only allowed prior to init(). All the additional vectors are similarly distributed, like the solution, and inititialized to zero.

By default vectors added by add_vector are projected to changed grids by reinit(). To zero them instead (more efficient), pass "false" as the second argument

Definition at line 511 of file system.C.

References _can_add_vectors, _vector_projections, _vectors, have_vector(), NumericVector< T >::init(), n_dofs(), n_local_dofs(), and libMeshEnums::PARALLEL.

Referenced by ExplicitSystem::add_system_rhs(), NonlinearImplicitSystem::adjoint_solve(), NewtonSolver::adjoint_solve(), LinearImplicitSystem::adjoint_solve(), UnsteadySolver::init(), ContinuationSystem::init_data(), NewmarkSystem::NewmarkSystem(), read_header(), FrequencySystem::set_frequencies(), FrequencySystem::set_frequencies_by_range(), and FrequencySystem::set_frequencies_by_steps().

00513 {
00514   // Return the vector if it is already there.
00515   if (this->have_vector(vec_name))
00516     return *(_vectors[vec_name]);
00517 
00518   // Otherwise build the vector
00519   NumericVector<Number>* buf = NumericVector<Number>::build().release();
00520   _vectors.insert (std::make_pair (vec_name, buf));
00521   _vector_projections.insert (std::make_pair (vec_name, projections));
00522 
00523   // Initialize it if necessary
00524   if (!_can_add_vectors)
00525     buf->init (this->n_dofs(), this->n_local_dofs(), false, PARALLEL);
00526 
00527   return *buf;
00528 }

virtual void System::adjoint_solve (  )  [pure virtual]

Solves the adjoint system. Must be overloaded in derived systems.

Implemented in DifferentiableSystem, EigenSystem, ExplicitSystem, LinearImplicitSystem, and NonlinearImplicitSystem.

Referenced by AdjointResidualErrorEstimator::estimate_error().

void System::assemble (  )  [virtual]

Prepares matrix and _dof_map for matrix assembly. Does not actually assemble anything. For matrix assembly, use the assemble() in derived classes. Should be overloaded in derived classes.

Reimplemented in DifferentiableSystem, EigenSystem, FrequencySystem, ImplicitSystem, and NewmarkSystem.

Definition at line 333 of file system.C.

References user_assembly().

Referenced by ImplicitSystem::assemble(), EigenSystem::assemble(), and ExplicitSystem::solve().

00334 {
00335   // Log how long the user's matrix assembly code takes
00336   START_LOG("assemble()", "System");
00337   
00338   // Call the user-specified assembly function
00339   this->user_assembly();
00340 
00341   // Stop logging the user code
00342   STOP_LOG("assemble()", "System");
00343 }

void System::assemble_qoi (  )  [virtual]

Calls user qoi function. Should be overloaded in derived classes.

Reimplemented in ExplicitSystem, and FEMSystem.

Definition at line 347 of file system.C.

References user_QOI().

Referenced by ExplicitSystem::assemble_qoi().

00348 {
00349   // Log how long the user's matrix assembly code takes
00350   START_LOG("assemble_qoi()", "System");
00351   
00352   // Call the user-specified quantity of interest function
00353   this->user_QOI();
00354 
00355   // Stop logging the user code
00356   STOP_LOG("assemble_qoi()", "System");
00357 }

void System::attach_assemble_function ( void   fptrEquationSystems &es,const std::string &name  ) 

Register a user function to use in assembling the system matrix and RHS.

Definition at line 1010 of file system.C.

References _assemble_system.

01012 {
01013   libmesh_assert (fptr != NULL);
01014   
01015   _assemble_system = fptr;  
01016 }

void System::attach_constraint_function ( void   fptrEquationSystems &es,const std::string &name  ) 

Register a user function for imposing constraints.

Definition at line 1020 of file system.C.

References _constrain_system.

01022 {
01023   libmesh_assert (fptr != NULL);
01024   
01025   _constrain_system = fptr;  
01026 }

void System::attach_init_function ( void   fptrEquationSystems &es,const std::string &name  ) 

Register a user function to use in initializing the system.

Definition at line 1000 of file system.C.

References _init_system.

01002 {
01003   libmesh_assert (fptr != NULL);
01004   
01005   _init_system = fptr;
01006 }

void System::attach_QOI_function ( void   fptrEquationSystems &es,const std::string &name  ) 

Register a user function for evaluating a quantity of interest

Definition at line 1030 of file system.C.

References _qoi_evaluate_system.

01032 {
01033   libmesh_assert (fptr != NULL);
01034   
01035   _qoi_evaluate_system = fptr;  
01036 }

Real System::calculate_norm ( NumericVector< Number > &  v,
const SystemNorm norm 
) const

Returns:
a norm of the vector v, using component_norm and component_scale to choose and weight the norms of each variable.

Definition at line 771 of file system.C.

References _dof_map, MeshBase::active_local_elements_begin(), MeshBase::active_local_elements_end(), TypeTensor< T >::add_scaled(), TypeVector< T >::add_scaled(), FEBase::build(), FEType::default_quadrature_rule(), dim, libMeshEnums::DISCRETE_L1, libMeshEnums::DISCRETE_L2, libMeshEnums::DISCRETE_L_INF, discrete_var_norm(), DofMap::dof_indices(), AutoPtr< Tp >::get(), get_dof_map(), get_mesh(), libMeshEnums::H1, libMeshEnums::H1_SEMINORM, libMeshEnums::H2, libMeshEnums::H2_SEMINORM, SystemNorm::is_discrete(), NumericVector< T >::l1_norm(), libMeshEnums::L2, NumericVector< T >::l2_norm(), libmesh_norm(), NumericVector< T >::linfty_norm(), NumericVector< T >::localize(), MeshBase::mesh_dimension(), n_vars(), libMeshEnums::SERIAL, NumericVector< T >::size(), TypeTensor< T >::size_sq(), TypeVector< T >::size_sq(), SystemNorm::type(), DofMap::variable_type(), and SystemNorm::weight().

00773 {
00774   // This function must be run on all processors at once
00775   parallel_only();
00776 
00777   START_LOG ("calculate_norm()", "System");
00778 
00779   // Zero the norm before summation
00780   Real v_norm = 0.;
00781 
00782   if (norm.is_discrete())
00783     {
00784       STOP_LOG ("calculate_norm()", "System");
00785       //Check to see if all weights are 1.0
00786       unsigned int check_var = 0;
00787       for (; check_var != this->n_vars(); ++check_var)
00788         if(norm.weight(check_var) != 1.0)
00789           break;
00790 
00791       //All weights were 1.0 so just do the full vector discrete norm
00792       if(check_var == this->n_vars())
00793         {
00794           FEMNormType norm_type = norm.type(0);
00795           
00796           if(norm_type == DISCRETE_L1)
00797             return v.l1_norm();
00798           if(norm_type == DISCRETE_L2)
00799             return v.l2_norm();
00800           if(norm_type == DISCRETE_L_INF)
00801             return v.linfty_norm();
00802           else
00803             libmesh_error();
00804         }
00805 
00806       for (unsigned int var=0; var != this->n_vars(); ++var)
00807         {
00808           // Skip any variables we don't need to integrate
00809           if (norm.weight(var) == 0.0)
00810             continue;
00811 
00812           v_norm += norm.weight(var) * discrete_var_norm(v, var, norm.type(var));
00813         }
00814 
00815       return v_norm;
00816     }
00817 
00818   // Localize the potentially parallel vector
00819   AutoPtr<NumericVector<Number> > local_v = NumericVector<Number>::build();
00820   local_v->init(v.size(), true, SERIAL);
00821   v.localize (*local_v, _dof_map->get_send_list()); 
00822 
00823   unsigned int dim = this->get_mesh().mesh_dimension();
00824 
00825   // Loop over all variables
00826   for (unsigned int var=0; var != this->n_vars(); ++var)
00827     {
00828       // Skip any variables we don't need to integrate
00829       if (norm.weight(var) == 0.0)
00830         continue;
00831 
00832       const FEType& fe_type = this->get_dof_map().variable_type(var);
00833       AutoPtr<QBase> qrule =
00834         fe_type.default_quadrature_rule (dim);
00835       AutoPtr<FEBase> fe
00836         (FEBase::build(dim, fe_type));
00837       fe->attach_quadrature_rule (qrule.get());
00838 
00839       const std::vector<Real>&               JxW = fe->get_JxW();
00840       const std::vector<std::vector<Real> >* phi = NULL;
00841       if (norm.type(var) == H1 ||
00842           norm.type(var) == H2 ||
00843           norm.type(var) == L2)
00844         phi = &(fe->get_phi());
00845 
00846       const std::vector<std::vector<RealGradient> >* dphi = NULL;
00847       if (norm.type(var) == H1 ||
00848           norm.type(var) == H2 ||
00849           norm.type(var) == H1_SEMINORM)
00850         dphi = &(fe->get_dphi());
00851 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
00852       const std::vector<std::vector<RealTensor> >*   d2phi = NULL;
00853       if (norm.type(var) == H2 ||
00854           norm.type(var) == H2_SEMINORM)
00855         d2phi = &(fe->get_d2phi());
00856 #endif
00857 
00858       std::vector<unsigned int> dof_indices;
00859 
00860       // Begin the loop over the elements
00861       MeshBase::const_element_iterator       el     =
00862         this->get_mesh().active_local_elements_begin();
00863       const MeshBase::const_element_iterator end_el =
00864         this->get_mesh().active_local_elements_end();
00865 
00866       for ( ; el != end_el; ++el)
00867         {
00868           const Elem* elem = *el;
00869 
00870           fe->reinit (elem);
00871 
00872           this->get_dof_map().dof_indices (elem, dof_indices, var);
00873 
00874           const unsigned int n_qp = qrule->n_points();
00875 
00876           const unsigned int n_sf = dof_indices.size();
00877 
00878           // Begin the loop over the Quadrature points.
00879           for (unsigned int qp=0; qp<n_qp; qp++)
00880             {
00881               if (norm.type(var) == H1 ||
00882                   norm.type(var) == H2 ||
00883                   norm.type(var) == L2)
00884                 {
00885                   Number u_h = 0.;
00886                   for (unsigned int i=0; i != n_sf; ++i)
00887                     u_h += (*phi)[i][qp] * (*local_v)(dof_indices[i]);
00888                   v_norm += norm.weight(var) * norm.weight(var) *
00889                             JxW[qp] * libmesh_norm(u_h);
00890                 }
00891 
00892               if (norm.type(var) == H1 ||
00893                   norm.type(var) == H2 ||
00894                   norm.type(var) == H1_SEMINORM)
00895                 {
00896                   Gradient grad_u_h;
00897                   for (unsigned int i=0; i != n_sf; ++i)
00898                     grad_u_h.add_scaled((*dphi)[i][qp], (*local_v)(dof_indices[i]));
00899                   v_norm += norm.weight(var) * norm.weight(var) *
00900                             JxW[qp] * grad_u_h.size_sq();
00901                 }
00902 
00903 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
00904               if (norm.type(var) == H2 ||
00905                   norm.type(var) == H2_SEMINORM)
00906                 {
00907                   Tensor hess_u_h;
00908                   for (unsigned int i=0; i != n_sf; ++i)
00909                     hess_u_h.add_scaled((*d2phi)[i][qp], (*local_v)(dof_indices[i]));
00910                   v_norm += norm.weight(var) * norm.weight(var) *
00911                             JxW[qp] * hess_u_h.size_sq();
00912                 }
00913 #endif
00914             }
00915         }
00916     }
00917 
00918   Parallel::sum(v_norm);
00919 
00920   STOP_LOG ("calculate_norm()", "System");
00921 
00922   return std::sqrt(v_norm);
00923 }

Real System::calculate_norm ( NumericVector< Number > &  v,
unsigned int  var = 0,
FEMNormType  norm_type = L2 
) const

Returns:
a norm of variable var in the vector v, in the specified norm (e.g. L2, H0, H1)

Definition at line 750 of file system.C.

References libMeshEnums::DISCRETE_L1, libMeshEnums::DISCRETE_L2, libMeshEnums::DISCRETE_L_INF, discrete_var_norm(), libMeshEnums::L2, and n_vars().

Referenced by AdaptiveTimeSolver::calculate_norm(), and UnsteadySolver::du().

00753 {
00754   //short circuit to save time
00755   if(norm_type == DISCRETE_L1 ||
00756      norm_type == DISCRETE_L2 ||
00757      norm_type == DISCRETE_L_INF)
00758     return discrete_var_norm(v,var,norm_type);
00759 
00760   // Not a discrete norm
00761   std::vector<FEMNormType> norms(this->n_vars(), L2);
00762   std::vector<Real> weights(this->n_vars(), 0.0);
00763   norms[var] = norm_type;
00764   weights[var] = 1.0;
00765   Real val = this->calculate_norm(v, SystemNorm(norms, weights));
00766   return val;
00767 }

void System::clear (  )  [virtual]

Clear all the data structures associated with the system.

Reimplemented in ContinuationSystem, DifferentiableSystem, EigenSystem, ExplicitSystem, FEMSystem, FrequencySystem, ImplicitSystem, LinearImplicitSystem, NewmarkSystem, and NonlinearImplicitSystem.

Definition at line 125 of file system.C.

References _can_add_vectors, _dof_map, _variable_numbers, _variables, _vector_projections, _vectors, current_local_solution, and solution.

Referenced by ExplicitSystem::clear(), EigenSystem::clear(), read_header(), and ~System().

00126 {
00127   _variables.clear();
00128   
00129   _variable_numbers.clear();
00130 
00131   _dof_map->clear ();
00132   
00133   solution->clear ();
00134 
00135   current_local_solution->clear ();
00136   
00137   // clear any user-added vectors
00138   {
00139     for (vectors_iterator pos = _vectors.begin(); pos != _vectors.end(); ++pos)
00140       {
00141         pos->second->clear ();
00142         delete pos->second;
00143         pos->second = NULL;
00144       }
00145     
00146     _vectors.clear();
00147     _vector_projections.clear();
00148     _can_add_vectors = true;
00149   }
00150 
00151 }

bool System::compare ( const System other_system,
const Real  threshold,
const bool  verbose 
) const [virtual]

Returns:
true when the other system contains identical data, up to the given threshold. Outputs some diagnostic info when verbose is set.

Definition at line 361 of file system.C.

References _can_add_vectors, _sys_name, _vectors, get_vector(), n_vectors(), name(), and solution.

Referenced by EquationSystems::compare().

00364 {
00365   // we do not care for matrices, but for vectors
00366   libmesh_assert (!_can_add_vectors);
00367   libmesh_assert (!other_system._can_add_vectors);
00368 
00369   if (verbose)
00370     {
00371       std::cout << "  Systems \"" << _sys_name << "\"" << std::endl;
00372       std::cout << "   comparing matrices not supported." << std::endl;
00373       std::cout << "   comparing names...";
00374     }
00375 
00376   // compare the name: 0 means identical
00377   const int name_result = _sys_name.compare(other_system.name());
00378   if (verbose)
00379     {
00380       if (name_result == 0)
00381         std::cout << " identical." << std::endl;
00382       else
00383         std::cout << "  names not identical." << std::endl;
00384       std::cout << "   comparing solution vector...";
00385     }
00386 
00387 
00388   // compare the solution: -1 means identical
00389   const int solu_result = solution->compare (*other_system.solution.get(),
00390                                              threshold);
00391 
00392   if (verbose)
00393     {
00394       if (solu_result == -1)
00395         std::cout << " identical up to threshold." << std::endl;
00396       else
00397         std::cout << "  first difference occured at index = " 
00398                   << solu_result << "." << std::endl;
00399     }
00400 
00401 
00402   // safety check, whether we handle at least the same number
00403   // of vectors
00404   std::vector<int> ov_result;
00405 
00406   if (this->n_vectors() != other_system.n_vectors())
00407     {
00408       if (verbose)
00409         {
00410           std::cout << "   Fatal difference. This system handles " 
00411                     << this->n_vectors() << " add'l vectors," << std::endl
00412                     << "   while the other system handles "
00413                     << other_system.n_vectors() 
00414                     << " add'l vectors." << std::endl
00415                     << "   Aborting comparison." << std::endl;
00416         }
00417       return false;
00418     }
00419   else if (this->n_vectors() == 0)
00420     {
00421       // there are no additional vectors...
00422       ov_result.clear ();
00423     }
00424   else
00425     {
00426       // compare other vectors
00427       for (const_vectors_iterator pos = _vectors.begin();
00428            pos != _vectors.end(); ++pos)
00429         {
00430           if (verbose)
00431               std::cout << "   comparing vector \""
00432                         << pos->first << "\" ...";
00433 
00434           // assume they have the same name
00435           const NumericVector<Number>& other_system_vector = 
00436               other_system.get_vector(pos->first);
00437 
00438           ov_result.push_back(pos->second->compare (other_system_vector,
00439                                                     threshold));
00440 
00441           if (verbose)
00442             {
00443               if (ov_result[ov_result.size()-1] == -1)
00444                 std::cout << " identical up to threshold." << std::endl;
00445               else
00446                 std::cout << " first difference occured at" << std::endl
00447                           << "   index = " << ov_result[ov_result.size()-1] << "." << std::endl;
00448             }
00449 
00450         }
00451 
00452     } // finished comparing additional vectors
00453 
00454 
00455   bool overall_result;
00456        
00457   // sum up the results
00458   if ((name_result==0) && (solu_result==-1))
00459     {
00460       if (ov_result.size()==0)
00461         overall_result = true;
00462       else
00463         {
00464           bool ov_identical;
00465           unsigned int n    = 0;
00466           do
00467             {
00468               ov_identical = (ov_result[n]==-1);
00469               n++;
00470             }
00471           while (ov_identical && n<ov_result.size());
00472           overall_result = ov_identical;
00473         }
00474     }
00475   else
00476     overall_result = false;
00477 
00478   if (verbose)
00479     {
00480       std::cout << "   finished comparisons, ";
00481       if (overall_result)
00482         std::cout << "found no differences." << std::endl << std::endl;
00483       else 
00484         std::cout << "found differences." << std::endl << std::endl;
00485     }
00486           
00487   return overall_result;
00488 }

Number System::current_solution ( const unsigned int  global_dof_number  )  const

Returns:
the current solution for the specified global DOF.

Definition at line 114 of file system.C.

References current_local_solution, and n_dofs().

Referenced by ExactSolution::_compute_error(), HPCoarsenTest::add_projection(), JumpErrorEstimator::estimate_error(), ExactErrorEstimator::estimate_error(), FEMSystem::eulerian_residual(), PatchRecoveryErrorEstimator::EstimateError::operator()(), FEMContext::reinit(), HPCoarsenTest::select_refinement(), VTKIO::solution_to_vtk(), EnsightIO::write_scalar_ascii(), and EnsightIO::write_vector_ascii().

00115 {
00116   // Check the sizes
00117   libmesh_assert (global_dof_number < _dof_map->n_dofs());
00118   libmesh_assert (global_dof_number < current_local_solution->size());
00119    
00120   return (*current_local_solution)(global_dof_number);
00121 }

void System::deactivate (  )  [inline]

Deactivates the system. Only active systems are solved.

Definition at line 1044 of file system.h.

References _active.

01045 {
01046   _active = false;
01047 }

Real System::discrete_var_norm ( NumericVector< Number > &  v,
unsigned int  var,
FEMNormType  norm_type 
) const [private]

Finds the discrete norm for the entries in the vector corresponding to Dofs associated with var.

Definition at line 733 of file system.C.

References libMeshEnums::DISCRETE_L1, libMeshEnums::DISCRETE_L2, libMeshEnums::DISCRETE_L_INF, local_dof_indices(), NumericVector< T >::subset_l1_norm(), NumericVector< T >::subset_l2_norm(), and NumericVector< T >::subset_linfty_norm().

Referenced by calculate_norm().

00736 {
00737   std::set<unsigned int> var_indices;
00738   local_dof_indices(var, var_indices);
00739 
00740   if(norm_type == DISCRETE_L1)
00741     return v.subset_l1_norm(var_indices);
00742   if(norm_type == DISCRETE_L2)
00743     return v.subset_l2_norm(var_indices);
00744   if(norm_type == DISCRETE_L_INF)
00745     return v.subset_linfty_norm(var_indices);
00746   else
00747     libmesh_error();
00748 }

NumericVector< Number > & System::get_adjoint_solution (  ) 

Returns:
a reference to the system's adjoint solution vector name adjoint_solution. Adjoint system needs to be solved first.

Definition at line 569 of file system.C.

References get_vector().

Referenced by AdjointResidualErrorEstimator::estimate_error().

00570 {
00571   // Get the adjoint solution using the get_vector function declared above
00572   return this->get_vector("adjoint_solution");
00573   
00574 }

DofMap & System::get_dof_map (  )  [inline]

Returns:
a writeable reference to this system's _dof_map.

Definition at line 1020 of file system.h.

References _dof_map.

01021 {
01022   return *_dof_map;
01023 }

EquationSystems& System::get_equation_systems (  )  [inline]

Returns:
a reference to this system's parent EquationSystems object.

Definition at line 242 of file system.h.

References _equation_systems.

00242 { return _equation_systems; }

std::string ReferenceCounter::get_info (  )  [static, inherited]

Gets a string containing the reference information.

Definition at line 45 of file reference_counter.C.

References ReferenceCounter::_counts, and QuadratureRules::name().

Referenced by ReferenceCounter::print_info().

00046 {
00047 #if defined(LIBMESH_ENABLE_REFERENCE_COUNTING) && defined(DEBUG)
00048 
00049   std::ostringstream out;
00050   
00051   out << '\n'
00052       << " ---------------------------------------------------------------------------- \n"
00053       << "| Reference count information                                                |\n"
00054       << " ---------------------------------------------------------------------------- \n";
00055   
00056   for (Counts::iterator it = _counts.begin();
00057        it != _counts.end(); ++it)
00058     {
00059       const std::string name(it->first);
00060       const unsigned int creations    = it->second.first;
00061       const unsigned int destructions = it->second.second;
00062 
00063       out << "| " << name << " reference count information:\n"
00064           << "|  Creations:    " << creations    << '\n'
00065           << "|  Destructions: " << destructions << '\n';
00066     }
00067   
00068   out << " ---------------------------------------------------------------------------- \n";
00069 
00070   return out.str();
00071 
00072 #else
00073 
00074   return "";
00075   
00076 #endif
00077 }

std::string System::get_info (  )  const

Returns:
a string containing information about the system.

Definition at line 927 of file system.C.

References Utility::enum_to_string< FEFamily >(), Utility::enum_to_string< InfMapType >(), Utility::enum_to_string< Order >(), FEType::family, get_dof_map(), FEType::inf_map, n_constrained_dofs(), n_dofs(), n_local_dofs(), n_vars(), n_vectors(), name(), FEType::order, FEType::radial_family, FEType::radial_order, system_type(), variable_name(), and DofMap::variable_type().

00928 {
00929   std::ostringstream out;
00930 
00931   
00932   const std::string& sys_name = this->name();
00933       
00934   out << "   System \"" << sys_name << "\"\n"
00935       << "    Type \""  << this->system_type() << "\"\n"
00936       << "    Variables=";
00937   
00938   for (unsigned int vn=0; vn<this->n_vars(); vn++)
00939       out << "\"" << this->variable_name(vn) << "\" ";
00940      
00941   out << '\n';
00942 
00943   out << "    Finite Element Types=";
00944 #ifndef LIBMESH_ENABLE_INFINITE_ELEMENTS
00945   for (unsigned int vn=0; vn<this->n_vars(); vn++)
00946     out << "\""
00947         << Utility::enum_to_string<FEFamily>(this->get_dof_map().variable_type(vn).family)
00948         << "\" ";  
00949 #else
00950   for (unsigned int vn=0; vn<this->n_vars(); vn++)
00951     {
00952       out << "\""
00953           << Utility::enum_to_string<FEFamily>(this->get_dof_map().variable_type(vn).family)
00954           << "\", \""
00955           << Utility::enum_to_string<FEFamily>(this->get_dof_map().variable_type(vn).radial_family)
00956           << "\" ";
00957     }
00958 
00959   out << '\n' << "    Infinite Element Mapping=";
00960   for (unsigned int vn=0; vn<this->n_vars(); vn++)
00961     out << "\""
00962         << Utility::enum_to_string<InfMapType>(this->get_dof_map().variable_type(vn).inf_map)
00963         << "\" ";
00964 #endif      
00965 
00966   out << '\n';
00967       
00968   out << "    Approximation Orders=";
00969   for (unsigned int vn=0; vn<this->n_vars(); vn++)
00970     {
00971 #ifndef LIBMESH_ENABLE_INFINITE_ELEMENTS
00972       out << "\""
00973           << Utility::enum_to_string<Order>(this->get_dof_map().variable_type(vn).order)
00974           << "\" ";
00975 #else
00976       out << "\""
00977           << Utility::enum_to_string<Order>(this->get_dof_map().variable_type(vn).order)
00978           << "\", \""
00979           << Utility::enum_to_string<Order>(this->get_dof_map().variable_type(vn).radial_order)
00980           << "\" ";
00981 #endif
00982     }
00983 
00984   out << '\n';
00985       
00986   out << "    n_dofs()="             << this->n_dofs()             << '\n';
00987   out << "    n_local_dofs()="       << this->n_local_dofs()       << '\n';
00988 #ifdef LIBMESH_ENABLE_AMR
00989   out << "    n_constrained_dofs()=" << this->n_constrained_dofs() << '\n';
00990 #endif
00991 
00992   out << "    " << "n_vectors()="  << this->n_vectors()  << '\n';
00993 //   out << "    " << "n_additional_matrices()=" << this->n_additional_matrices() << '\n';
00994   
00995   return out.str();
00996 }

MeshBase & System::get_mesh (  )  [inline]

Returns:
a reference to this systems's _mesh.

Definition at line 1004 of file system.h.

References _mesh.

01005 {
01006   return _mesh;
01007 }

NumericVector< Number > & System::get_vector ( const std::string &  vec_name  ) 

Returns:
a writeable reference to this system's additional vector named vec_name. Access is only granted when the vector is already properly initialized.

Definition at line 551 of file system.C.

References _vectors.

00552 {
00553   // Make sure the vector exists
00554   vectors_iterator pos = _vectors.find(vec_name);
00555   
00556   if (pos == _vectors.end())
00557     {
00558       std::cerr << "ERROR: vector "
00559                 << vec_name
00560                 << " does not exist in this system!"
00561                 << std::endl;      
00562       libmesh_error();
00563     }
00564   
00565   return *(pos->second);
00566 }

const NumericVector< Number > & System::get_vector ( const std::string &  vec_name  )  const

Returns:
a const reference to this system's additional vector named vec_name. Access is only granted when the vector is already properly initialized.

Definition at line 532 of file system.C.

References _vectors.

Referenced by UnsteadySolver::advance_timestep(), AdaptiveTimeSolver::advance_timestep(), compare(), UnsteadySolver::du(), get_adjoint_solution(), NewmarkSystem::initial_conditions(), UnsteadySolver::solve(), TwostepTimeSolver::solve(), FrequencySystem::solve(), NewmarkSystem::update_rhs(), and NewmarkSystem::update_u_v_a().

00533 {
00534   // Make sure the vector exists
00535   const_vectors_iterator pos = _vectors.find(vec_name);
00536   
00537   if (pos == _vectors.end())
00538     {
00539       std::cerr << "ERROR: vector "
00540                 << vec_name
00541                 << " does not exist in this system!"
00542                 << std::endl;      
00543       libmesh_error();
00544     }
00545   
00546   return *(pos->second);
00547 }

bool System::has_variable ( const std::string &  var  )  const

Returns:
true if a variable named var exists in this System

Definition at line 629 of file system.C.

References _variable_numbers.

Referenced by GMVIO::copy_nodal_solution().

00630 {
00631   return _variable_numbers.count(var);
00632 }

bool System::have_vector ( const std::string &  vec_name  )  const [inline]

Returns:
true if this System has a vector associated with the given name, false otherwise.

Definition at line 1106 of file system.h.

References _vectors.

Referenced by add_vector().

01107 {
01108   return (_vectors.count(vec_name));
01109 }

void ReferenceCounter::increment_constructor_count ( const std::string &  name  )  [inline, protected, inherited]

Increments the construction counter. Should be called in the constructor of any derived class that will be reference counted.

Definition at line 149 of file reference_counter.h.

References ReferenceCounter::_counts, and Threads::spin_mtx.

Referenced by ReferenceCountedObject< SparseMatrix< T > >::ReferenceCountedObject().

00150 {
00151   Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
00152   std::pair<unsigned int, unsigned int>& p = _counts[name];
00153 
00154   p.first++;
00155 }

void ReferenceCounter::increment_destructor_count ( const std::string &  name  )  [inline, protected, inherited]

Increments the destruction counter. Should be called in the destructor of any derived class that will be reference counted.

Definition at line 167 of file reference_counter.h.

References ReferenceCounter::_counts, and Threads::spin_mtx.

Referenced by ReferenceCountedObject< SparseMatrix< T > >::~ReferenceCountedObject().

00168 {
00169   Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
00170   std::pair<unsigned int, unsigned int>& p = _counts[name];
00171 
00172   p.second++;
00173 }

void System::init (  ) 

Initializes degrees of freedom on the current mesh. Sets the

Definition at line 155 of file system.C.

References init_data(), n_vars(), and user_initialization().

00156 { 
00157   // First initialize any required data
00158   this->init_data();
00159   
00160   //If no variables have been added to this system
00161   //don't do anything
00162   if(!this->n_vars())
00163     return;
00164  
00165   // Then call the user-provided intialization function
00166   this->user_initialization();
00167 }

void System::init_data (  )  [protected, virtual]

Initializes the data for the system. Note that this is called before any user-supplied intitialization function so that all required storage will be available.

Reimplemented in ContinuationSystem, DifferentiableSystem, EigenSystem, ExplicitSystem, FEMSystem, FrequencySystem, and ImplicitSystem.

Definition at line 171 of file system.C.

References _can_add_vectors, _dof_map, _vectors, current_local_solution, get_mesh(), libMeshEnums::GHOSTED, mesh, n_dofs(), n_local_dofs(), libMeshEnums::PARALLEL, libMeshEnums::SERIAL, solution, and user_constrain().

Referenced by init(), ExplicitSystem::init_data(), and EigenSystem::init_data().

00172 {
00173   MeshBase &mesh = this->get_mesh();
00174 
00175   // Distribute the degrees of freedom on the mesh
00176   _dof_map->distribute_dofs (mesh);
00177 
00178 #ifdef LIBMESH_ENABLE_AMR
00179 
00180   // Recreate any hanging node constraints
00181   _dof_map->create_dof_constraints(mesh);
00182 
00183   // Apply any user-defined constraints
00184   this->user_constrain();
00185 
00186   // Expand any recursive constraints
00187   _dof_map->process_constraints();
00188 
00189   // And clean up the send_list before we first use it
00190   _dof_map->prepare_send_list();
00191 
00192 #endif
00193   
00194   // Resize the solution conformal to the current mesh
00195   solution->init (this->n_dofs(), this->n_local_dofs(), false, PARALLEL);
00196 
00197   // Resize the current_local_solution for the current mesh
00198 #ifdef LIBMESH_ENABLE_GHOSTED
00199   current_local_solution->init (this->n_dofs(), this->n_local_dofs(),
00200                                 _dof_map->get_send_list(), false,
00201                                 GHOSTED);
00202 #else
00203   current_local_solution->init (this->n_dofs(), false, SERIAL);
00204 #endif
00205 
00206   // from now on, no chance to add additional vectors
00207   _can_add_vectors = false;
00208 
00209   // initialize & zero other vectors, if necessary
00210   for (vectors_iterator pos = _vectors.begin(); pos != _vectors.end(); ++pos)
00211       pos->second->init (this->n_dofs(), this->n_local_dofs(), false, PARALLEL);
00212 }

void System::local_dof_indices ( const unsigned int  var,
std::set< unsigned int > &  var_indices 
) const

Fills the std::set with the degrees of freedom on the local processor corresponding the the variable number passed in.

Definition at line 656 of file system.C.

References MeshBase::active_local_elements_begin(), MeshBase::active_local_elements_end(), DofMap::dof_indices(), DofMap::end_dof(), DofMap::first_dof(), get_dof_map(), and get_mesh().

Referenced by discrete_var_norm().

00657 {
00658   // Make sure the set is clear
00659   var_indices.clear();
00660 
00661   std::vector<unsigned int> dof_indices;
00662   
00663   // Begin the loop over the elements
00664   MeshBase::const_element_iterator       el     =
00665     this->get_mesh().active_local_elements_begin();
00666   const MeshBase::const_element_iterator end_el =
00667     this->get_mesh().active_local_elements_end();
00668 
00669   const unsigned int 
00670     first_local = this->get_dof_map().first_dof(),
00671     end_local   = this->get_dof_map().end_dof();
00672 
00673   for ( ; el != end_el; ++el)
00674     {
00675       const Elem* elem = *el;      
00676       this->get_dof_map().dof_indices (elem, dof_indices, var);
00677 
00678       for(unsigned int i=0; i<dof_indices.size(); i++)
00679         {
00680           unsigned int dof = dof_indices[i];
00681 
00682           //If the dof is owned by the local processor
00683           if(first_local <= dof && dof < end_local)
00684             var_indices.insert(dof_indices[i]);
00685         }
00686     }
00687 }

unsigned int System::n_active_dofs (  )  const [inline]

Returns the number of active degrees of freedom for this System.

Definition at line 1098 of file system.h.

References n_constrained_dofs(), and n_dofs().

01099 {
01100   return this->n_dofs() - this->n_constrained_dofs();
01101 }

unsigned int System::n_constrained_dofs (  )  const

Returns:
the number of constrained degrees of freedom in the system.

Definition at line 92 of file system.C.

References _dof_map.

Referenced by get_info(), and n_active_dofs().

00093 {
00094 #ifdef LIBMESH_ENABLE_AMR
00095 
00096   return _dof_map->n_constrained_dofs();
00097 
00098 #else
00099 
00100   return 0;
00101 
00102 #endif
00103 }

unsigned int System::n_dofs (  )  const

Returns:
the number of degrees of freedom in the system

Definition at line 85 of file system.C.

References _dof_map.

Referenced by add_vector(), current_solution(), get_info(), init_data(), FEMSystem::mass_residual(), n_active_dofs(), System::ProjectVector::operator()(), project_vector(), read_legacy_data(), reinit(), restrict_vectors(), and UnsteadySolver::solve().

00086 {
00087   return _dof_map->n_dofs();
00088 }

unsigned int System::n_local_dofs (  )  const

Returns:
the number of degrees of freedom local to this processor

Definition at line 107 of file system.C.

References _dof_map, and libMesh::processor_id().

Referenced by add_vector(), get_info(), init_data(), project_vector(), read_serialized_blocked_dof_objects(), reinit(), restrict_vectors(), and UnsteadySolver::solve().

00108 {
00109   return _dof_map->n_dofs_on_processor (libMesh::processor_id());
00110 }

static unsigned int ReferenceCounter::n_objects (  )  [inline, static, inherited]

Prints the number of outstanding (created, but not yet destroyed) objects.

Definition at line 76 of file reference_counter.h.

References ReferenceCounter::_n_objects.

00077   { return _n_objects; }

unsigned int System::n_vectors (  )  const [inline]

Returns:
the number of vectors (in addition to the solution) handled by this system This is the size of the _vectors map

Definition at line 1114 of file system.h.

References _vectors.

Referenced by ExplicitSystem::add_system_rhs(), compare(), get_info(), read_header(), and write_header().

01115 {
01116   return _vectors.size(); 
01117 }

void ReferenceCounter::print_info (  )  [static, inherited]

Prints the reference information to std::cout.

Definition at line 83 of file reference_counter.C.

References ReferenceCounter::get_info().

00084 {
00085 #if defined(LIBMESH_ENABLE_REFERENCE_COUNTING) && defined(DEBUG)
00086   
00087   std::cout << ReferenceCounter::get_info();
00088   
00089 #endif
00090 }

void System::project_solution ( Number   fptrconst Point &p,const Parameters &parameters,const std::string &sys_name,const std::string &unknown_name,
Gradient   gptrconst Point &p,const Parameters &parameters,const std::string &sys_name,const std::string &unknown_name,
Parameters parameters 
) const

Projects the continuous functions onto the current solution.

This method projects an analytic function onto the solution via L2 projections and nodal interpolations on each element.

Definition at line 221 of file system_projection.C.

References current_local_solution, project_vector(), and solution.

00230 {
00231   this->project_vector(fptr, gptr, parameters, *solution);
00232 
00233   solution->localize(*current_local_solution);
00234 }

bool& System::project_solution_on_reinit ( void   )  [inline]

Tells the System whether or not to project the solution vector onto new grids when the system is reinitialized. The solution will be projected unless project_solution_on_reinit() = false is called.

Definition at line 304 of file system.h.

References _solution_projection.

00305     { return _solution_projection; }

void System::project_vector ( const NumericVector< Number > &  old_v,
NumericVector< Number > &  new_v 
) const [protected]

Projects the vector defined on the old mesh onto the new mesh. The original vector is unchanged and the new vector is passed through the second argument.

This method projects the vector via L2 projections or nodal interpolations on each element.

This method projects a solution from an old mesh to a current, refined mesh. The input vector old_v gives the solution on the old mesh, while the new_v gives the solution (to be computed) on the new mesh.

Definition at line 60 of file system_projection.C.

References NumericVector< T >::clear(), NumericVector< T >::close(), DofMap::enforce_constraints_exactly(), FEType::family, AutoPtr< Tp >::get(), get_dof_map(), get_mesh(), libMeshEnums::GHOSTED, NumericVector< T >::init(), NumericVector< T >::local_size(), NumericVector< T >::localize(), n_dofs(), n_local_dofs(), n_vars(), libMeshEnums::PARALLEL, Threads::parallel_for(), Threads::parallel_reduce(), libMeshEnums::SCALAR, System::BuildProjectionList::send_list, libMeshEnums::SERIAL, NumericVector< T >::set(), NumericVector< T >::size(), NumericVector< T >::type(), System::Variable::type(), System::BuildProjectionList::unique(), and variable().

00062 {
00063   START_LOG ("project_vector()", "System");
00064 
00071   new_v.clear();
00072 
00073 #ifdef LIBMESH_ENABLE_AMR
00074 
00075   // First make sure we don't have any SCALAR variables, since
00076   // vector projection is not yet implemented for SCALARs
00077   for(unsigned int v=0; v<this->n_vars(); v++)
00078     if(this->variable(v).type().family == SCALAR)
00079       libmesh_not_implemented();
00080 
00081   // Resize the new vector and get a serial version.
00082   NumericVector<Number> *new_vector_ptr = NULL;
00083   AutoPtr<NumericVector<Number> > new_vector_built;
00084   NumericVector<Number> *local_old_vector;
00085   AutoPtr<NumericVector<Number> > local_old_vector_built;
00086   const NumericVector<Number> *old_vector_ptr = NULL;
00087 
00088   ConstElemRange active_local_elem_range 
00089     (this->get_mesh().active_local_elements_begin(),
00090      this->get_mesh().active_local_elements_end());
00091 
00092   // If the old vector was uniprocessor, make the new
00093   // vector uniprocessor
00094   if (old_v.type() == SERIAL)
00095     {
00096       new_v.init (this->n_dofs(), false, SERIAL);
00097       new_vector_ptr = &new_v;
00098       old_vector_ptr = &old_v;
00099     }
00100 
00101   // Otherwise it is a parallel, distributed vector, which
00102   // we need to localize.
00103   else if (old_v.type() == PARALLEL)
00104     {
00105       // Build a send list for efficient localization
00106       BuildProjectionList projection_list(*this);
00107       Threads::parallel_reduce (active_local_elem_range, 
00108                                 projection_list);
00109 
00110       // Create a sorted, unique send_list
00111       projection_list.unique();
00112 
00113       new_v.init (this->n_dofs(), this->n_local_dofs(), false, PARALLEL);
00114       new_vector_built = NumericVector<Number>::build();
00115       local_old_vector_built = NumericVector<Number>::build();
00116       new_vector_ptr = new_vector_built.get();
00117       local_old_vector = local_old_vector_built.get();
00118       new_vector_ptr->init(this->n_dofs(), false, SERIAL);
00119       local_old_vector->init(old_v.size(), false, SERIAL);
00120       old_v.localize(*local_old_vector, projection_list.send_list);
00121       local_old_vector->close();
00122       old_vector_ptr = local_old_vector;
00123     }
00124   else if (old_v.type() == GHOSTED)
00125     {
00126       // Build a send list for efficient localization
00127       BuildProjectionList projection_list(*this);
00128       Threads::parallel_reduce (active_local_elem_range, 
00129                                 projection_list);
00130 
00131       // Create a sorted, unique send_list
00132       projection_list.unique();
00133 
00134       new_v.init (this->n_dofs(), this->n_local_dofs(),
00135                   this->get_dof_map().get_send_list(), false, GHOSTED);
00136 
00137       local_old_vector_built = NumericVector<Number>::build();
00138       new_vector_ptr = &new_v;
00139       local_old_vector = local_old_vector_built.get();
00140       local_old_vector->init(old_v.size(), old_v.local_size(),
00141                              projection_list.send_list, false, GHOSTED);
00142       old_v.localize(*local_old_vector, projection_list.send_list);
00143       local_old_vector->close();
00144       old_vector_ptr = local_old_vector;
00145     }
00146   else // unknown old_v.type()
00147     {
00148       std::cerr << "ERROR: Unknown old_v.type() == " << old_v.type() 
00149                 << std::endl;
00150       libmesh_error();
00151     }
00152   
00153   // Note that the above will have zeroed the new_vector.
00154   // Just to be sure, assert that new_vector_ptr and old_vector_ptr
00155   // were successfully set before trying to deref them.
00156   libmesh_assert(new_vector_ptr);
00157   libmesh_assert(old_vector_ptr);
00158 
00159   NumericVector<Number> &new_vector = *new_vector_ptr;
00160   const NumericVector<Number> &old_vector = *old_vector_ptr;
00161     
00162   Threads::parallel_for (active_local_elem_range,
00163                          ProjectVector(*this,
00164                                        old_vector,
00165                                        new_vector)
00166                          );
00167 
00168   new_vector.close();
00169 
00170   // If the old vector was serial, we probably need to send our values
00171   // to other processors
00172   //
00173   // FIXME: I'm not sure how to make a NumericVector do that without
00174   // creating a temporary parallel vector to use localize! - RHS
00175   if (old_v.type() == SERIAL)
00176     {
00177       AutoPtr<NumericVector<Number> > dist_v = NumericVector<Number>::build();
00178       dist_v->init(this->n_dofs(), this->n_local_dofs(), false, PARALLEL);
00179       dist_v->close();
00180     
00181       for (unsigned int i=0; i!=dist_v->size(); i++)
00182         if (new_vector(i) != 0.0)
00183           dist_v->set(i, new_vector(i));
00184 
00185       dist_v->close();
00186 
00187       dist_v->localize (new_v, this->get_dof_map().get_send_list());
00188       new_v.close();
00189     }
00190   // If the old vector was parallel, we need to update it
00191   // and free the localized copies
00192   else if (old_v.type() == PARALLEL)
00193     {
00194       // We may have to set dof values that this processor doesn't
00195       // own in certain special cases, like LAGRANGE FIRST or
00196       // HERMITE THIRD elements on second-order meshes
00197       for (unsigned int i=0; i!=new_v.size(); i++)
00198         if (new_vector(i) != 0.0)
00199           new_v.set(i, new_vector(i));
00200       new_v.close();
00201     }
00202 
00203   this->get_dof_map().enforce_constraints_exactly(*this, &new_v);
00204 
00205 #else
00206 
00207   // AMR is disabled: simply copy the vector
00208   new_v = old_v;
00209   
00210 #endif // #ifdef LIBMESH_ENABLE_AMR
00211 
00212   STOP_LOG("project_vector()", "System");
00213 }

void System::project_vector ( NumericVector< Number > &  vector  )  const [protected]

Projects the vector defined on the old mesh onto the new mesh.

Definition at line 43 of file system_projection.C.

References NumericVector< T >::clone(), and project_vector().

00044 {
00045   // Create a copy of the vector, which currently
00046   // contains the old data.
00047   AutoPtr<NumericVector<Number> >
00048     old_vector (vector.clone());
00049 
00050   // Project the old vector to the new vector
00051   this->project_vector (*old_vector, vector);
00052 }

void System::project_vector ( Number   fptrconst Point &p,const Parameters &parameters,const std::string &sys_name,const std::string &unknown_name,
Gradient   gptrconst Point &p,const Parameters &parameters,const std::string &sys_name,const std::string &unknown_name,
Parameters parameters,
NumericVector< Number > &  new_vector 
) const

Projects the continuous functions onto the current mesh.

This method projects an analytic function via L2 projections and nodal interpolations on each element.

Definition at line 242 of file system_projection.C.

References NumericVector< T >::close(), DofMap::enforce_constraints_exactly(), get_dof_map(), get_mesh(), and Threads::parallel_for().

Referenced by project_solution(), project_vector(), and restrict_vectors().

00252 {
00253   START_LOG ("project_vector()", "System");
00254 
00255   Threads::parallel_for (ConstElemRange (this->get_mesh().active_local_elements_begin(),
00256                                          this->get_mesh().active_local_elements_end(),
00257                                          1000),
00258                          ProjectSolution(*this,
00259                                          fptr,
00260                                          gptr,
00261                                          parameters,
00262                                          new_vector)
00263                          );
00264 
00265 
00266   new_vector.close();
00267 
00268 #ifdef LIBMESH_ENABLE_AMR
00269   this->get_dof_map().enforce_constraints_exactly(*this, &new_vector);
00270 #endif
00271 
00272   STOP_LOG("project_vector()", "System");
00273 }

void System::prolong_vectors (  )  [virtual]

Prolong vectors after the mesh has refined

Definition at line 252 of file system.C.

References restrict_vectors().

Referenced by EquationSystems::reinit().

00253 {
00254 #ifdef LIBMESH_ENABLE_AMR
00255   // Currently project_vector handles both restriction and prolongation
00256   this->restrict_vectors();
00257 #endif
00258 }

void System::re_update (  )  [virtual]

Re-update the local values when the mesh has changed. This method takes the data updated by update() and makes it up-to-date on the current mesh.

Definition at line 311 of file system.C.

References current_local_solution, Utility::iota(), and solution.

00312 {
00313   //const std::vector<unsigned int>& send_list = _dof_map->get_send_list ();
00314 
00315   // Explicitly build a send_list
00316   std::vector<unsigned int> send_list(solution->size());
00317   Utility::iota (send_list.begin(), send_list.end(), 0);
00318   
00319   // Check sizes
00320   libmesh_assert (current_local_solution->size()       == solution->size());
00321   // Not true with ghosted vectors
00322   // libmesh_assert (current_local_solution->local_size() == solution->size());
00323   libmesh_assert (!send_list.empty());
00324   libmesh_assert (send_list.size() <= solution->size());
00325 
00326   // Create current_local_solution from solution.  This will
00327   // put a local copy of solution into current_local_solution.
00328   solution->localize (*current_local_solution, send_list);
00329 }

void System::read_header ( Xdr io,
const std::string &  version,
const bool  read_header = true,
const bool  read_additional_data = true,
const bool  read_legacy_format = false 
)

Reads the basic data header for this System.

Definition at line 78 of file system_io.C.

References _additional_data_written, _can_add_vectors, add_variable(), add_vector(), clear(), Xdr::data(), FEType::family, get_mesh(), FEType::inf_map, MeshBase::mesh_dimension(), libMeshEnums::MONOMIAL, n_vars(), n_vectors(), libMesh::on_command_line(), FEType::order, libMesh::processor_id(), FEType::radial_family, FEType::radial_order, Xdr::reading(), type, and libMeshEnums::XYZ.

Referenced by EquationSystems::_read_impl().

00083 {
00084   // This method implements the input of a
00085   // System object, embedded in the output of
00086   // an EquationSystems<T_sys>.  This warrants some 
00087   // documentation.  The output file essentially
00088   // consists of 5 sections:
00089   //
00090   // for this system
00091   //
00092   //   5.) The number of variables in the system (unsigned int)
00093   //
00094   //   for each variable in the system
00095   //     
00096   //     6.) The name of the variable (string)
00097   //     
00098   //     7.) Combined in an FEType:
00099   //         - The approximation order(s) of the variable 
00100   //           (Order Enum, cast to int/s)
00101   //         - The finite element family/ies of the variable 
00102   //           (FEFamily Enum, cast to int/s)
00103   // 
00104   //   end variable loop
00105   //
00106   //   8.) The number of additional vectors (unsigned int),      
00107   //
00108   //     for each additional vector in the system object
00109   // 
00110   //     9.) the name of the additional vector  (string)
00111   //
00112   // end system
00113   libmesh_assert (io.reading());
00114   
00115   // Possibly clear data structures and start from scratch.
00116   if (read_header)
00117     this->clear ();
00118 
00119   // Figure out if we need to read infinite element information.
00120   // This will be true if the version string contains " with infinite elements"
00121   const bool read_ifem_info =
00122     (version.rfind(" with infinite elements") < version.size()) ||
00123     libMesh::on_command_line ("--read_ifem_systems");
00124   
00125   
00126   {
00127     // 5.) 
00128     // Read the number of variables in the system
00129     unsigned int n_vars=0;
00130     if (libMesh::processor_id() == 0) io.data (n_vars);
00131     Parallel::broadcast(n_vars);
00132       
00133     for (unsigned int var=0; var<n_vars; var++)
00134       {             
00135         // 6.)
00136         // Read the name of the var-th variable
00137         std::string var_name;     
00138         if (libMesh::processor_id() == 0) io.data (var_name);
00139         Parallel::broadcast(var_name);
00140                 
00141         // 7.)
00142         // Read the approximation order(s) of the var-th variable 
00143         int order=0;      
00144         if (libMesh::processor_id() == 0) io.data (order);
00145         Parallel::broadcast(order);
00146         
00147         
00148         // do the same for infinite element radial_order 
00149         int rad_order=0;
00150         if (read_ifem_info)
00151           {
00152             if (libMesh::processor_id() == 0) io.data(rad_order);
00153             Parallel::broadcast(rad_order);
00154           }
00155 
00156 
00157         // Read the finite element type of the var-th variable 
00158         int fam=0;
00159         if (libMesh::processor_id() == 0) io.data (fam);
00160         Parallel::broadcast(fam);
00161         FEType type;
00162         type.order  = static_cast<Order>(order);
00163         type.family = static_cast<FEFamily>(fam);
00164 
00165         // Check for incompatibilities.  The shape function indexing was
00166         // changed for the monomial and xyz finite element families to 
00167         // simplify extension to arbitrary p.  The consequence is that 
00168         // old restart files will not be read correctly.  This is expected
00169         // to be an unlikely occurance, but catch it anyway.
00170         if (read_legacy_format)
00171           if ((type.family == MONOMIAL || type.family == XYZ) && 
00172               ((type.order > 2 && this->get_mesh().mesh_dimension() == 2) ||
00173                (type.order > 1 && this->get_mesh().mesh_dimension() == 3)))
00174             {
00175               libmesh_here();
00176               std::cout << "*****************************************************************\n"
00177                         << "* WARNING: reading a potentially incompatible restart file!!!   *\n"
00178                         << "*  contact libmesh-users@lists.sourceforge.net for more details *\n"
00179                         << "*****************************************************************"
00180                         << std::endl;
00181             }
00182                         
00183         // Read additional information for infinite elements    
00184         int radial_fam=0;
00185         int i_map=0;
00186         if (read_ifem_info)
00187           {
00188             if (libMesh::processor_id() == 0) io.data (radial_fam);
00189             Parallel::broadcast(radial_fam);
00190             if (libMesh::processor_id() == 0) io.data (i_map);
00191             Parallel::broadcast(i_map);
00192           }
00193         
00194 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
00195         
00196         type.radial_order  = static_cast<Order>(rad_order);
00197         type.radial_family = static_cast<FEFamily>(radial_fam);
00198         type.inf_map       = static_cast<InfMapType>(i_map);      
00199 
00200 #endif
00201 
00202         if (read_header) 
00203           this->add_variable (var_name, type);
00204       }
00205   }
00206 
00207   // 8.)  
00208   // Read the number of additional vectors.  
00209   unsigned int n_vectors=0;  
00210   if (libMesh::processor_id() == 0) io.data (n_vectors);
00211   Parallel::broadcast(n_vectors);
00212   
00213   // If n_vectors > 0, this means that write_additional_data
00214   // was true when this file was written.  We will need to
00215   // make use of this fact later.
00216   if (n_vectors > 0)
00217     this->_additional_data_written = true;  
00218   
00219   for (unsigned int vec=0; vec<n_vectors; vec++)
00220     {
00221       // 9.)
00222       // Read the name of the vec-th additional vector
00223       std::string vec_name;      
00224       if (libMesh::processor_id() == 0) io.data (vec_name);
00225       Parallel::broadcast(vec_name);
00226       
00227       if (read_additional_data)
00228         {
00229           // sanity checks
00230           libmesh_assert(this->_can_add_vectors);
00231           // Some systems may have added their own vectors already
00232 //        libmesh_assert(this->_vectors.count(vec_name) == 0);
00233 
00234           this->add_vector(vec_name);
00235         }
00236     }
00237 }

void System::read_legacy_data ( Xdr io,
const bool  read_additional_data = true 
)

Reads additional data, namely vectors, for this System.

Definition at line 241 of file system_io.C.

References _additional_data_written, _vectors, MeshBase::active_elements_begin(), MeshBase::active_elements_end(), Xdr::data(), get_mesh(), DofObject::invalid_id, n_dofs(), n_vars(), MeshBase::nodes_begin(), MeshBase::nodes_end(), number(), libMesh::processor_id(), Xdr::reading(), solution, and libMesh::zero.

00243 {
00244   deprecated();
00245   
00246   // This method implements the output of the vectors
00247   // contained in this System object, embedded in the 
00248   // output of an EquationSystems<T_sys>. 
00249   //
00250   //   10.) The global solution vector, re-ordered to be node-major 
00251   //       (More on this later.)                                    
00252   //                                                                
00253   //      for each additional vector in the object          
00254   //                                                                
00255   //      11.) The global additional vector, re-ordered to be       
00256   //           node-major (More on this later.)
00257   libmesh_assert (io.reading());
00258 
00259   // read and reordering buffers
00260   std::vector<Number> global_vector;
00261   std::vector<Number> reordered_vector;
00262 
00263   // 10.)
00264   // Read and set the solution vector
00265   {     
00266     if (libMesh::processor_id() == 0) io.data (global_vector);    
00267     Parallel::broadcast(global_vector);
00268     
00269     // Remember that the stored vector is node-major.
00270     // We need to put it into whatever application-specific
00271     // ordering we may have using the dof_map.
00272     reordered_vector.resize(global_vector.size());
00273 
00274     //std::cout << "global_vector.size()=" << global_vector.size() << std::endl;
00275     //std::cout << "this->n_dofs()=" << this->n_dofs() << std::endl;
00276     
00277     libmesh_assert (global_vector.size() == this->n_dofs());
00278         
00279     unsigned int cnt=0;
00280 
00281     const unsigned int sys     = this->number();
00282     const unsigned int n_vars  = this->n_vars();
00283 
00284     for (unsigned int var=0; var<n_vars; var++)
00285       { 
00286         // First reorder the nodal DOF values
00287         {
00288           MeshBase::node_iterator
00289             it  = this->get_mesh().nodes_begin(),
00290             end = this->get_mesh().nodes_end();
00291         
00292           for (; it != end; ++it)
00293             for (unsigned int index=0; index<(*it)->n_comp(sys,var); index++)
00294               {
00295                 libmesh_assert ((*it)->dof_number(sys, var, index) !=
00296                         DofObject::invalid_id);
00297                 
00298                 libmesh_assert (cnt < global_vector.size());
00299                 
00300                 reordered_vector[(*it)->dof_number(sys, var, index)] =
00301                   global_vector[cnt++]; 
00302               }
00303         }
00304         
00305         // Then reorder the element DOF values
00306         {
00307           MeshBase::element_iterator
00308             it  = this->get_mesh().active_elements_begin(),
00309             end = this->get_mesh().active_elements_end();
00310 
00311           for (; it != end; ++it)
00312             for (unsigned int index=0; index<(*it)->n_comp(sys,var); index++)
00313               {  
00314                 libmesh_assert ((*it)->dof_number(sys, var, index) !=
00315                         DofObject::invalid_id);
00316                 
00317                 libmesh_assert (cnt < global_vector.size());
00318                 
00319                 reordered_vector[(*it)->dof_number(sys, var, index)] =
00320                   global_vector[cnt++]; 
00321               }
00322         }
00323       }
00324             
00325     *(this->solution) = reordered_vector;
00326   }
00327 
00328   // For each additional vector, simply go through the list.
00329   // ONLY attempt to do this IF additional data was actually
00330   // written to the file for this system (controlled by the
00331   // _additional_data_written flag).  
00332   if (this->_additional_data_written)
00333     {
00334       std::map<std::string, NumericVector<Number>* >::iterator
00335         pos = this->_vectors.begin();
00336   
00337       for (; pos != this->_vectors.end(); ++pos)
00338         {
00339           // 11.)          
00340           // Read the values of the vec-th additional vector.
00341           // Prior do _not_ clear, but fill with zero, since the
00342           // additional vectors _have_ to have the same size
00343           // as the solution vector
00344           std::fill (global_vector.begin(), global_vector.end(), libMesh::zero);
00345 
00346           if (libMesh::processor_id() == 0) io.data (global_vector);
00347           Parallel::broadcast(global_vector);
00348 
00349           // If read_additional_data==true, then we will keep this vector, otherwise
00350           // we are going to throw it away.
00351           if (read_additional_data)
00352             {
00353               // Remember that the stored vector is node-major.
00354               // We need to put it into whatever application-specific
00355               // ordering we may have using the dof_map.
00356               std::fill (reordered_vector.begin(),
00357                          reordered_vector.end(),
00358                          libMesh::zero);
00359         
00360               reordered_vector.resize(global_vector.size());    
00361 
00362               libmesh_assert (global_vector.size() == this->n_dofs());
00363         
00364               unsigned int cnt=0;
00365 
00366               const unsigned int sys     = this->number();
00367               const unsigned int n_vars  = this->n_vars();
00368         
00369               for (unsigned int var=0; var<n_vars; var++)
00370                 {
00371                   // First reorder the nodal DOF values
00372                   {
00373                     MeshBase::node_iterator
00374                       it  = this->get_mesh().nodes_begin(),
00375                       end = this->get_mesh().nodes_end();
00376 
00377                     for (; it!=end; ++it)
00378                       for (unsigned int index=0; index<(*it)->n_comp(sys,var); index++)
00379                         {
00380                           libmesh_assert ((*it)->dof_number(sys, var, index) !=
00381                                   DofObject::invalid_id);
00382                           
00383                           libmesh_assert (cnt < global_vector.size());
00384                           
00385                           reordered_vector[(*it)->dof_number(sys, var, index)] =
00386                             global_vector[cnt++]; 
00387                         }
00388                   }
00389 
00390                   // Then reorder the element DOF values
00391                   {
00392                     MeshBase::element_iterator
00393                       it  = this->get_mesh().active_elements_begin(),
00394                       end = this->get_mesh().active_elements_end();
00395 
00396                     for (; it!=end; ++it)
00397                       for (unsigned int index=0; index<(*it)->n_comp(sys,var); index++)
00398                         {  
00399                           libmesh_assert ((*it)->dof_number(sys, var, index) !=
00400                                   DofObject::invalid_id);
00401                           
00402                           libmesh_assert (cnt < global_vector.size());
00403                           
00404                           reordered_vector[(*it)->dof_number(sys, var, index)] =
00405                             global_vector[cnt++]; 
00406                         }
00407                   }
00408                 }
00409             
00410               // use the overloaded operator=(std::vector) to assign the values
00411               *(pos->second) = reordered_vector;
00412             }
00413         }
00414     } // end if (_additional_data_written)    
00415 }

void System::read_parallel_data ( Xdr io,
const bool  read_additional_data 
)

Reads additional data, namely vectors, for this System. This method may safely be called on a distributed-memory mesh. This method will read an individual file for each processor in the simulation where the local solution components for that processor are stored.

This method implements the output of the vectors contained in this System object, embedded in the output of an EquationSystems<T_sys>.

9.) The global solution vector, re-ordered to be node-major (More on this later.)

for each additional vector in the object

10.) The global additional vector, re-ordered to be node-major (More on this later.)

Note that the actual IO is handled through the Xdr class (to be renamed later?) which provides a uniform interface to both the XDR (eXternal Data Representation) interface and standard ASCII output. Thus this one section of code will read XDR or ASCII files with no changes.

Definition at line 419 of file system_io.C.

References _vectors, Xdr::data(), get_mesh(), DofObject::invalid_id, Xdr::is_open(), n_vars(), number(), Xdr::reading(), and solution.

00421 {
00441   libmesh_assert (io.reading());
00442   libmesh_assert (io.is_open());
00443 
00444   // build the ordered nodes and element maps.
00445   // when writing/reading parallel files we need to iterate
00446   // over our nodes/elements in order of increasing global id().
00447   // however, this is not guaranteed to be ordering we obtain
00448   // by using the node_iterators/element_iterators directly.
00449   // so build a set, sorted by id(), that provides the ordering.
00450   // further, for memory economy build the set but then transfer
00451   // its contents to vectors, which will be sorted.
00452   std::vector<const DofObject*> ordered_nodes, ordered_elements;
00453   {    
00454     std::set<const DofObject*, CompareDofObjectsByID>
00455       ordered_nodes_set (this->get_mesh().local_nodes_begin(),
00456                          this->get_mesh().local_nodes_end());
00457       
00458       ordered_nodes.insert(ordered_nodes.end(),
00459                            ordered_nodes_set.begin(),
00460                            ordered_nodes_set.end());
00461   }
00462   {
00463     std::set<const DofObject*, CompareDofObjectsByID>
00464       ordered_elements_set (this->get_mesh().local_elements_begin(),
00465                             this->get_mesh().local_elements_end());
00466       
00467       ordered_elements.insert(ordered_elements.end(),
00468                               ordered_elements_set.begin(),
00469                               ordered_elements_set.end());
00470   }
00471   
00472   std::vector<Number> io_buffer;
00473   
00474   // 9.)
00475   //
00476   // Actually read the solution components
00477   // for the ith system to disk
00478   io.data(io_buffer);
00479   
00480   const unsigned int sys_num = this->number();
00481   const unsigned int n_vars  = this->n_vars();
00482 
00483   unsigned int cnt=0;
00484   
00485   // Loop over each variable and each node, and read out the value.
00486   for (unsigned int var=0; var<n_vars; var++)
00487     {
00488       // First read the node DOF values
00489       for (std::vector<const DofObject*>::const_iterator
00490              it = ordered_nodes.begin(); it != ordered_nodes.end(); ++it)
00491         for (unsigned int comp=0; comp<(*it)->n_comp(sys_num, var); comp++)
00492           {
00493             libmesh_assert ((*it)->dof_number(sys_num, var, comp) !=
00494                     DofObject::invalid_id);
00495             libmesh_assert (cnt < io_buffer.size());
00496             this->solution->set((*it)->dof_number(sys_num, var, comp), io_buffer[cnt++]);
00497           }
00498 
00499       // Then read the element DOF values
00500       for (std::vector<const DofObject*>::const_iterator
00501              it = ordered_elements.begin(); it != ordered_elements.end(); ++it)
00502         for (unsigned int comp=0; comp<(*it)->n_comp(sys_num, var); comp++)
00503           {
00504             libmesh_assert ((*it)->dof_number(sys_num, var, comp) !=
00505                     DofObject::invalid_id);
00506             libmesh_assert (cnt < io_buffer.size());
00507             this->solution->set((*it)->dof_number(sys_num, var, comp), io_buffer[cnt++]);
00508           }      
00509     }
00510   
00511   // Only read additional vectors if wanted  
00512   if (read_additional_data)
00513     {     
00514       std::map<std::string, NumericVector<Number>* >::const_iterator
00515         pos = _vectors.begin();
00516   
00517       for(; pos != this->_vectors.end(); ++pos)
00518         {
00519           cnt=0;
00520           io_buffer.clear();
00521           
00522           // 10.)
00523           //
00524           // Actually read the additional vector components
00525           // for the ith system to disk
00526           io.data(io_buffer);
00527           
00528           // Loop over each variable and each node, and read out the value.
00529           for (unsigned int var=0; var<n_vars; var++)
00530             {
00531               // First read the node DOF values
00532               for (std::vector<const DofObject*>::const_iterator
00533                      it = ordered_nodes.begin(); it != ordered_nodes.end(); ++it)
00534                 for (unsigned int comp=0; comp<(*it)->n_comp(sys_num, var); comp++)
00535                   {
00536                     libmesh_assert ((*it)->dof_number(sys_num, var, comp) !=
00537                             DofObject::invalid_id);
00538                     libmesh_assert (cnt < io_buffer.size());
00539                     this->solution->set((*it)->dof_number(sys_num, var, comp), io_buffer[cnt++]);
00540                   }          
00541               
00542               // Then read the element DOF values
00543               for (std::vector<const DofObject*>::const_iterator
00544                      it = ordered_elements.begin(); it != ordered_elements.end(); ++it)
00545                 for (unsigned int comp=0; comp<(*it)->n_comp(sys_num, var); comp++)
00546                   {
00547                     libmesh_assert ((*it)->dof_number(sys_num, var, comp) !=
00548                             DofObject::invalid_id);
00549                     libmesh_assert (cnt < io_buffer.size());
00550                     this->solution->set((*it)->dof_number(sys_num, var, comp), io_buffer[cnt++]);
00551                   }           
00552             }
00553         }
00554     }
00555 }

template<typename iterator_type >
unsigned int System::read_serialized_blocked_dof_objects ( const unsigned int  var,
const unsigned int  n_objects,
const iterator_type  begin,
const iterator_type  end,
Xdr io,
NumericVector< Number > &  vec 
) const [inline, private]

Reads an input vector from the stream io and assigns the values to a set of DofObjects. This method uses blocked input and is safe to call on a distributed memory-mesh.

Definition at line 608 of file system_io.C.

References Xdr::data_stream(), NumericVector< T >::first_local_index(), MeshTools::Generation::Private::idx(), libMesh::invalid_uint, io_blksize, NumericVector< T >::last_local_index(), std::min(), n_local_dofs(), libMesh::n_processors(), number(), libMesh::processor_id(), and NumericVector< T >::set().

Referenced by read_serialized_vector().

00614 {
00615   const unsigned int sys_num = this->number();
00616   
00617   std::vector<Number> input_buffer;        // buffer to hold the input block read from io.               
00618   std::vector<Number> local_values;
00619   std::vector<std::vector<unsigned int> >  // The IDs from each processor which map to the objects
00620     recv_ids(libMesh::n_processors());     //  read in the current block
00621   std::vector<unsigned int> idx_map;       // Reordering map to traverse entry-wise rather than processor-wise
00622   unsigned int n_assigned_vals = 0;        // the number of values assigned, this will be returned.
00623   
00624   //-----------------------------------
00625   // Collect the values for all objects
00626   unsigned int first_object=0, last_object=0;
00627 
00628   for (unsigned int blk=0; last_object<n_objects; blk++)
00629     {
00630       //std::cout << "Reading object block " << blk << std::endl;
00631       
00632       // Each processor should build up its transfer buffers for its
00633       // local objects in [first_object,last_object).
00634       first_object = blk*io_blksize;
00635       last_object  = std::min((blk+1)*io_blksize,n_objects);
00636       
00637       // Clear the transfer buffers for this block.
00638       recv_ids[libMesh::processor_id()].clear();
00639       unsigned int n_local_dofs=0;
00640       for (iterator_type it=begin; it!=end; ++it)
00641         if (((*it)->id() >= first_object) && // object in [first_object,last_object)
00642             ((*it)->id() <   last_object) &&
00643             (*it)->n_comp(sys_num,var))      // var has a nonzero # of components on this object
00644           {
00645             recv_ids[libMesh::processor_id()].push_back((*it)->id());
00646             recv_ids[libMesh::processor_id()].push_back((*it)->n_comp(sys_num, var));
00647             recv_ids[libMesh::processor_id()].push_back(n_local_dofs);
00648             n_local_dofs += (*it)->n_comp(sys_num, var);            
00649           }
00650       
00651       // Get the recv_ids for all other processors.
00652       {
00653         const unsigned int curr_vec_size = recv_ids[libMesh::processor_id()].size();
00654         std::vector<unsigned int> recv_id_sizes(libMesh::n_processors());
00655         Parallel::allgather(curr_vec_size, recv_id_sizes);
00656         for (unsigned int pid=0; pid<libMesh::n_processors(); pid++)
00657           {
00658             recv_ids[pid].resize(recv_id_sizes[pid]);
00659             Parallel::broadcast(recv_ids[pid], pid);
00660           }
00661       }
00662 
00663       // create the idx map for all processors -- this will match the ordering
00664       // in the input buffer chunk which we are about to read.
00665       idx_map.resize(3*io_blksize); std::fill (idx_map.begin(), idx_map.end(), libMesh::invalid_uint);
00666       unsigned int tot_n_comp=0;
00667       for (unsigned int pid=0; pid<libMesh::n_processors(); pid++)
00668         for (unsigned int idx=0; idx<recv_ids[pid].size(); idx+=3)
00669           {
00670             const unsigned int local_idx = recv_ids[pid][idx+0]-first_object;
00671             libmesh_assert (local_idx < std::min(io_blksize,n_objects));
00672             const unsigned int n_comp    = recv_ids[pid][idx+1];
00673             const unsigned int start_pos = recv_ids[pid][idx+2];
00674             
00675             idx_map[3*local_idx+0] = pid;
00676             idx_map[3*local_idx+1] = n_comp;
00677             idx_map[3*local_idx+2] = start_pos; // this tells us where the values
00678                                                 // for this object will live in the local_values buffer
00679             tot_n_comp += n_comp;
00680           }
00681       
00682       // Processor 0 will read the block from the buffer stream and send it to all other processors
00683       input_buffer.resize (tot_n_comp);
00684       if (libMesh::processor_id() == 0) io.data_stream(input_buffer.empty() ? NULL : &input_buffer[0], tot_n_comp);
00685       Parallel::broadcast(input_buffer);
00686 
00687       // Extract the values corresponding to the local objects from the input_buffer
00688       // and place them into the local_values temporary buffer.
00689       {
00690         unsigned int processed_size=0;
00691         std::vector<Number>::const_iterator next_value = input_buffer.begin();
00692         local_values.clear(); local_values.resize(n_local_dofs);
00693 
00694         for (unsigned int idx=0; idx<idx_map.size(); idx+=3)
00695           if (idx_map[idx] != libMesh::invalid_uint) // this could happen when an object
00696             {                                        // has no components for the current variable
00697               const unsigned int pid       = idx_map[idx+0];
00698               const unsigned int n_comp    = idx_map[idx+1];
00699               const unsigned int start_pos = idx_map[idx+2];
00700               
00701               for (unsigned int comp=0; comp<n_comp; comp++)
00702                 {
00703                   libmesh_assert (next_value != input_buffer.end());
00704                   if (pid == libMesh::processor_id())
00705                     {
00706                       libmesh_assert ((start_pos+comp) < local_values.size());
00707                       local_values[start_pos+comp] = *next_value;
00708                     }
00709                   ++next_value;
00710                   ++processed_size;                             
00711                 }
00712             }
00713         libmesh_assert (processed_size == input_buffer.size());
00714       }
00715       
00716       // A subset of the components (potentially null set) will match our objects in
00717       // [first_object,last_object), and we will assign the corresponding values from
00718       // the local_values buffer.
00719       for (iterator_type it=begin; it!=end; ++it)
00720         if (((*it)->id() >= first_object) && // object in [first_object,last_object)
00721             ((*it)->id() <   last_object) &&
00722             (*it)->n_comp(sys_num,var))      // var has a nonzero # of components on this object
00723           {
00724             const unsigned int local_idx = (*it)->id()-first_object;
00725             libmesh_assert (local_idx < std::min(io_blksize,n_objects));
00726 
00727 #ifndef NDEBUG
00728             // We only need to check the pid when asserts are active
00729             const unsigned int pid       = idx_map[3*local_idx+0];
00730 #endif
00731             libmesh_assert (pid == libMesh::processor_id());
00732             
00733             const unsigned int n_comp    = idx_map[3*local_idx+1];
00734             const unsigned int start_pos = idx_map[3*local_idx+2];
00735             
00736             libmesh_assert (n_comp == (*it)->n_comp(sys_num, var));
00737             
00738             for (unsigned int comp=0; comp<n_comp; comp++)
00739               {
00740                 libmesh_assert ((start_pos+comp) < local_values.size());
00741                 const Number &value = local_values[start_pos+comp];                             
00742                 const unsigned int dof_index = (*it)->dof_number (sys_num, var, comp);
00743                 libmesh_assert (dof_index >= vec.first_local_index());
00744                 libmesh_assert (dof_index <  vec.last_local_index());
00745                 //std::cout << "di=" << dof_index << ", val=" << value << std::endl;
00746                 vec.set (dof_index, value);
00747                 ++n_assigned_vals;
00748               }
00749           }
00750     }
00751       
00752   return n_assigned_vals;
00753 }

void System::read_serialized_data ( Xdr io,
const bool  read_additional_data = true 
)

Reads additional data, namely vectors, for this System. This method may safely be called on a distributed-memory mesh.

Definition at line 559 of file system_io.C.

References _vectors, Xdr::comment(), libMesh::processor_id(), read_serialized_vector(), and solution.

00561 {
00562   // This method implements the input of the vectors
00563   // contained in this System object, embedded in the 
00564   // output of an EquationSystems<T_sys>. 
00565   //
00566   //   10.) The global solution vector, re-ordered to be node-major 
00567   //       (More on this later.)                                    
00568   //                                                                
00569   //      for each additional vector in the object          
00570   //                                                                
00571   //      11.) The global additional vector, re-ordered to be       
00572   //          node-major (More on this later.)
00573   parallel_only();
00574   std::string comment;
00575 
00576   // 10.)
00577   // Read the global solution vector
00578   {
00579     this->read_serialized_vector(io, *this->solution); 
00580 
00581     // get the comment
00582     if (libMesh::processor_id() == 0)
00583       io.comment (comment);  
00584   }
00585   
00586   // 11.)
00587   // Only read additional vectors if wanted  
00588   if (read_additional_data)
00589     {     
00590       std::map<std::string, NumericVector<Number>* >::const_iterator
00591         pos = _vectors.begin();
00592   
00593       for(; pos != this->_vectors.end(); ++pos)
00594         {
00595           this->read_serialized_vector(io, *pos->second);
00596 
00597           // get the comment
00598           if (libMesh::processor_id() == 0)
00599             io.comment (comment);         
00600             
00601         }
00602     }
00603 }

void System::read_serialized_vector ( Xdr io,
NumericVector< Number > &  vec 
) [private]

Reads a vector for this System. This method may safely be called on a distributed-memory mesh.

Definition at line 757 of file system_io.C.

References NumericVector< T >::close(), Xdr::data(), get_mesh(), io_blksize, MeshTools::n_elem(), n_nodes, libMesh::n_processors(), n_vars(), libMeshEnums::PARALLEL, libMesh::processor_id(), read_serialized_blocked_dof_objects(), Xdr::reading(), and NumericVector< T >::type().

Referenced by read_serialized_data().

00758 {
00759   parallel_only();
00760 
00761 #ifndef NDEBUG
00762   // In parallel we better be reading a parallel vector -- if not
00763   // we will not set all of its components below!!
00764   if (libMesh::n_processors() > 1)
00765     libmesh_assert (vec.type() == PARALLEL);
00766    
00767   // If this is not the same on all processors we're in trouble!
00768   Parallel::verify(io_blksize);
00769 #endif
00770   
00771   libmesh_assert (io.reading());
00772 
00773   // vector length
00774   unsigned int vector_length=0, n_assigned_vals=0;
00775 
00776   // Get the buffer size
00777   if (libMesh::processor_id() == 0) io.data(vector_length, "# vector length");
00778   Parallel::broadcast(vector_length);
00779   
00780   // Loop over each variable in the system, and then each node/element in the mesh.
00781   for (unsigned int var=0; var<this->n_vars(); var++)
00782     {      
00783       //---------------------------------
00784       // Collect the values for all nodes
00785       n_assigned_vals +=
00786         this->read_serialized_blocked_dof_objects (var,
00787                                                    this->get_mesh().n_nodes(),
00788                                                    this->get_mesh().local_nodes_begin(),
00789                                                    this->get_mesh().local_nodes_end(),
00790                                                    io,
00791                                                    vec);
00792       
00793       
00794       //------------------------------------
00795       // Collect the values for all elements
00796       n_assigned_vals +=
00797         this->read_serialized_blocked_dof_objects (var,
00798                                                    this->get_mesh().n_elem(),
00799                                                    this->get_mesh().local_elements_begin(),
00800                                                    this->get_mesh().local_elements_end(),
00801                                                    io,
00802                                                    vec);
00803     } // end variable loop
00804 
00805   vec.close();
00806 
00807 #ifndef NDEBUG
00808   Parallel::sum (n_assigned_vals);
00809   libmesh_assert (n_assigned_vals == vector_length);
00810 #endif
00811 }

void System::reinit (  )  [virtual]

Reinitializes degrees of freedom and other required data on the current mesh. Note that the matrix is not initialized at this time since it may not be required for all applications. Should be overloaded in derived classes.

Reimplemented in DifferentiableSystem, EigenSystem, ExplicitSystem, ImplicitSystem, LinearImplicitSystem, NewmarkSystem, and NonlinearImplicitSystem.

Definition at line 262 of file system.C.

References current_local_solution, n_dofs(), n_local_dofs(), n_vars(), libMeshEnums::PARALLEL, and solution.

Referenced by ExplicitSystem::reinit(), and EigenSystem::reinit().

00263 {
00264 #ifdef LIBMESH_ENABLE_AMR
00265   //If no variables have been added to this system
00266   //don't do anything
00267   if(!this->n_vars())
00268     return;
00269 
00270   // Constraints get handled in EquationSystems::reinit now
00271 //  _dof_map->create_dof_constraints(this->get_mesh());
00272 
00273   // Update the solution based on the projected
00274   // current_local_solution.
00275   solution->init (this->n_dofs(), this->n_local_dofs(), true, PARALLEL);
00276         
00277   libmesh_assert (solution->size() == current_local_solution->size());
00278   // Not true with ghosted vectors
00279   // libmesh_assert (solution->size() == current_local_solution->local_size());
00280 
00281   const unsigned int first_local_dof = solution->first_local_index();
00282   const unsigned int local_size      = solution->local_size();
00283       
00284   for (unsigned int i=0; i<local_size; i++)
00285     solution->set(i+first_local_dof,
00286                   (*current_local_solution)(i+first_local_dof));
00287 #endif
00288 }

void System::restrict_vectors (  )  [virtual]

Restrict vectors after the mesh has coarsened

Definition at line 216 of file system.C.

References _dof_map, _solution_projection, _vector_projections, _vectors, current_local_solution, libMeshEnums::GHOSTED, NumericVector< T >::init(), n_dofs(), n_local_dofs(), libMeshEnums::PARALLEL, project_vector(), and solution.

Referenced by prolong_vectors(), and EquationSystems::reinit().

00217 {
00218 #ifdef LIBMESH_ENABLE_AMR
00219   // Restrict the _vectors on the coarsened cells
00220   for (vectors_iterator pos = _vectors.begin(); pos != _vectors.end(); ++pos)
00221     {
00222       NumericVector<Number>* v = pos->second;
00223       
00224       if (_vector_projections[pos->first])
00225         this->project_vector (*v);
00226       else
00227         v->init (this->n_dofs(), this->n_local_dofs(), false, PARALLEL);
00228     }
00229 
00230   const std::vector<unsigned int>& send_list = _dof_map->get_send_list ();
00231 
00232   // Restrict the solution on the coarsened cells
00233   if (_solution_projection)
00234     this->project_vector (*solution);
00235 
00236 #ifdef LIBMESH_ENABLE_GHOSTED
00237   current_local_solution->init(this->n_dofs(),
00238                                this->n_local_dofs(), send_list, 
00239                                false, GHOSTED);
00240 #else
00241   current_local_solution->init(this->n_dofs());
00242 #endif
00243 
00244   if (_solution_projection)
00245     solution->localize (*current_local_solution, send_list); 
00246 
00247 #endif // LIBMESH_ENABLE_AMR
00248 }

virtual void System::solve (  )  [pure virtual]

Solves the system. Must be overloaded in derived systems.

Implemented in ContinuationSystem, DifferentiableSystem, EigenSystem, ExplicitSystem, FEMSystem, FrequencySystem, LinearImplicitSystem, and NonlinearImplicitSystem.

sys_type& System::system (  )  [inline]

Returns:
a clever pointer to the system.

Reimplemented in EigenSystem, ExplicitSystem, ImplicitSystem, LinearImplicitSystem, and NonlinearImplicitSystem.

Definition at line 94 of file system.h.

00094 { return *this; }

virtual std::string System::system_type (  )  const [inline, virtual]

Returns:
the type of system, helpful in identifying which system type to use when reading equation system data from file. Should be overloaded in derived classes.

Reimplemented in EigenSystem, ExplicitSystem, FrequencySystem, ImplicitSystem, LinearImplicitSystem, NewmarkSystem, and NonlinearImplicitSystem.

Definition at line 165 of file system.h.

Referenced by get_info().

00165 { return "BasicSystem"; }

void System::update (  )  [virtual]

Update the local values to reflect the solution on neighboring processors.

Definition at line 292 of file system.C.

References _dof_map, current_local_solution, and solution.

Referenced by __libmesh_petsc_diff_solver_jacobian(), __libmesh_petsc_diff_solver_residual(), PetscDiffSolver::adjoint_solve(), NonlinearImplicitSystem::adjoint_solve(), NewtonSolver::adjoint_solve(), LinearImplicitSystem::adjoint_solve(), FEMSystem::assemble_qoi(), FEMSystem::assembly(), Problem_Interface::computeF(), GMVIO::copy_nodal_solution(), AdjointResidualErrorEstimator::estimate_error(), FEMSystem::mesh_position_get(), FEMSystem::postprocess(), NonlinearImplicitSystem::solve(), NewtonSolver::solve(), LinearImplicitSystem::solve(), and ExplicitSystem::solve().

00293 {
00294   const std::vector<unsigned int>& send_list = _dof_map->get_send_list ();
00295 
00296   // Check sizes
00297   libmesh_assert (current_local_solution->size() == solution->size());
00298 // More processors than elements => empty send_list
00299 //  libmesh_assert (!send_list.empty());
00300   libmesh_assert (send_list.size() <= solution->size());
00301 
00302   // Create current_local_solution from solution.  This will
00303   // put a local copy of solution into current_local_solution.
00304   // Only the necessary values (specified by the send_list)
00305   // are copied to minimize communication
00306   solution->localize (*current_local_solution, send_list); 
00307 }

void System::update_global_solution ( std::vector< Number > &  global_soln,
const unsigned int  dest_proc 
) const

Fill the input vector global_soln so that it contains the global solution on processor dest_proc. Requires communication with all other processors.

Definition at line 501 of file system.C.

References solution.

00503 {
00504   global_soln.resize        (solution->size());
00505 
00506   solution->localize_to_one (global_soln, dest_proc);
00507 }

void System::update_global_solution ( std::vector< Number > &  global_soln  )  const

Fill the input vector global_soln so that it contains the global solution on all processors. Requires communication with all other processors.

Definition at line 492 of file system.C.

References solution.

Referenced by ExactSolution::_compute_error(), EquationSystems::build_discontinuous_solution_vector(), EquationSystems::build_solution_vector(), and ExactErrorEstimator::estimate_error().

00493 {
00494   global_soln.resize (solution->size());
00495 
00496   solution->localize (global_soln);
00497 }

void System::user_assembly (  )  [virtual]

Calls user's attached assembly function, or is overloaded by the user in derived classes.

Definition at line 1049 of file system.C.

References _assemble_system, _equation_systems, and name().

Referenced by assemble().

01050 {
01051   // Call the user-provided assembly function,
01052   // if it was provided
01053   if (_assemble_system != NULL)
01054     this->_assemble_system (_equation_systems, this->name());
01055 }

void System::user_constrain (  )  [virtual]

Calls user's attached constraint function, or is overloaded by the user in derived classes.

Definition at line 1059 of file system.C.

References _constrain_system, _equation_systems, and name().

Referenced by init_data(), and EquationSystems::reinit().

01060 {
01061   // Call the user-provided constraint function, 
01062   // if it was provided
01063   if(_constrain_system!= NULL)
01064     this->_constrain_system(_equation_systems, this->name());
01065 }

void System::user_initialization (  )  [virtual]

Calls user's attached initialization function, or is overloaded by the user in derived classes.

Definition at line 1040 of file system.C.

References _equation_systems, _init_system, and name().

Referenced by init(), and NewmarkSystem::initial_conditions().

01041 {
01042   // Call the user-provided intialization function,
01043   // if it was provided
01044   if (_init_system != NULL)
01045     this->_init_system (_equation_systems, this->name());
01046 }

void System::user_QOI (  )  [virtual]

Calls user's attached quantity of interest function, or is overloaded by the user in derived classes.

Definition at line 1069 of file system.C.

References _equation_systems, _qoi_evaluate_system, and name().

Referenced by assemble_qoi().

01070 {
01071   // Call the user-provided quantity of interest function, 
01072   // if it was provided
01073   if(_qoi_evaluate_system!= NULL)
01074     this->_qoi_evaluate_system(_equation_systems, this->name());
01075 }

const System::Variable & System::variable ( unsigned int  var  )  const [inline]

Return a constant reference to Variable var.

Definition at line 1060 of file system.h.

References _variables.

Referenced by EquationSystems::build_solution_vector(), and project_vector().

01061 {
01062   libmesh_assert (i < _variables.size());
01063 
01064   return _variables[i];
01065 }

const std::string & System::variable_name ( const unsigned int  i  )  const [inline]

unsigned short int System::variable_number ( const std::string &  var  )  const

Returns:
the variable number assoicated with the user-specified variable named var.

Definition at line 636 of file system.C.

References _variable_numbers, and _variables.

Referenced by ExactSolution::_compute_error(), GMVIO::copy_nodal_solution(), ExactErrorEstimator::estimate_error(), variable_type(), EnsightIO::write_scalar_ascii(), and EnsightIO::write_vector_ascii().

00637 {
00638   // Make sure the variable exists
00639   std::map<std::string, unsigned short int>::const_iterator
00640     pos = _variable_numbers.find(var);
00641   
00642   if (pos == _variable_numbers.end())
00643     {
00644       std::cerr << "ERROR: variable "
00645                 << var
00646                 << " does not exist in this system!"
00647                 << std::endl;      
00648       libmesh_error();
00649     }
00650   libmesh_assert (_variables[pos->second].name() == var);
00651 
00652   return pos->second;
00653 }

const FEType & System::variable_type ( const std::string &  var  )  const [inline]

Returns:
the finite element type for variable var.

Definition at line 1090 of file system.h.

References _variables, and variable_number().

01091 {
01092   return _variables[this->variable_number(var)].type();
01093 }

const FEType & System::variable_type ( const unsigned int  i  )  const [inline]

Returns:
the finite element type variable number i.

Definition at line 1080 of file system.h.

References _variables.

Referenced by add_variable(), EquationSystems::build_discontinuous_solution_vector(), EquationSystems::build_solution_vector(), GMVIO::copy_nodal_solution(), FEMContext::FEMContext(), write_header(), EnsightIO::write_scalar_ascii(), and EnsightIO::write_vector_ascii().

01081 {
01082   libmesh_assert (i < _variables.size());
01083   
01084   return _variables[i].type();
01085 }

System::const_vectors_iterator System::vectors_begin (  )  const [inline]

Beginning of vectors container

Definition at line 1126 of file system.h.

References _vectors.

01127 {
01128   return _vectors.begin();
01129 }

System::vectors_iterator System::vectors_begin (  )  [inline]

Beginning of vectors container

Definition at line 1120 of file system.h.

References _vectors.

Referenced by VTKIO::system_vectors_to_vtk().

01121 {
01122   return _vectors.begin();
01123 }

System::const_vectors_iterator System::vectors_end (  )  const [inline]

End of vectors container

Definition at line 1138 of file system.h.

References _vectors.

01139 {
01140   return _vectors.end();
01141 }

System::vectors_iterator System::vectors_end (  )  [inline]

End of vectors container

Definition at line 1132 of file system.h.

References _vectors.

Referenced by VTKIO::system_vectors_to_vtk().

01133 {
01134   return _vectors.end();
01135 }

void System::write_header ( Xdr io,
const std::string &  version,
const bool  write_additional_data 
) const

Writes the basic data header for this System.

This method implements the output of a System object, embedded in the output of an EquationSystems<T_sys>. This warrants some documentation. The output of this part consists of 5 sections:

for this system

5.) The number of variables in the system (unsigned int)

for each variable in the system

6.) The name of the variable (string)

7.) Combined in an FEType:

  • The approximation order(s) of the variable (Order Enum, cast to int/s)
  • The finite element family/ies of the variable (FEFamily Enum, cast to int/s)

end variable loop

8.) The number of additional vectors (unsigned int),

for each additional vector in the system object

9.) the name of the additional vector (string)

end system

Definition at line 815 of file system_io.C.

References _vectors, Xdr::data(), FEType::family, get_mesh(), FEType::inf_map, n_vars(), n_vectors(), name(), FEType::order, MeshBase::processor_id(), FEType::radial_family, FEType::radial_order, type, variable_name(), variable_type(), and Xdr::writing().

00818 {
00850   libmesh_assert (io.writing());
00851 
00852 
00853   // Only write the header information
00854   // if we are processor 0.
00855   if (this->get_mesh().processor_id() != 0)
00856     return;
00857   
00858   std::string comment;
00859   char buf[80];
00860 
00861   // 5.) 
00862   // Write the number of variables in the system
00863 
00864   {
00865     // set up the comment
00866     comment = "# No. of Variables in System \"";
00867     comment += this->name();
00868     comment += "\"";    
00869           
00870     unsigned int n_vars = this->n_vars();   
00871     io.data (n_vars, comment.c_str());
00872   }
00873 
00874 
00875   for (unsigned int var=0; var<this->n_vars(); var++)
00876     {
00877       // 6.)
00878       // Write the name of the var-th variable
00879       {
00880         // set up the comment
00881         comment  = "#   Name, Variable No. ";
00882         std::sprintf(buf, "%d", var);
00883         comment += buf;
00884         comment += ", System \"";
00885         comment += this->name();
00886         comment += "\"";
00887               
00888         std::string var_name = this->variable_name(var);             
00889         io.data (var_name, comment.c_str());
00890       }
00891       
00892       // 7.)
00893       // Write the approximation order of the var-th variable 
00894       // in this system
00895       {
00896         // set up the comment
00897         comment = "#     Approximation Order, Variable \"";
00898         std::sprintf(buf, "%s", this->variable_name(var).c_str());
00899         comment += buf;
00900         comment += "\", System \"";
00901         comment += this->name();
00902         comment += "\"";
00903               
00904         int order = static_cast<int>(this->variable_type(var).order);         
00905         io.data (order, comment.c_str());
00906       }
00907 
00908 
00909 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
00910       
00911       // do the same for radial_order
00912       {
00913         comment = "#     Radial Approximation Order, Variable \"";
00914         std::sprintf(buf, "%s", this->variable_name(var).c_str());
00915         comment += buf;
00916         comment += "\", System \"";
00917         comment += this->name();
00918         comment += "\"";
00919       
00920         int rad_order = static_cast<int>(this->variable_type(var).radial_order);              
00921         io.data (rad_order, comment.c_str());
00922       }
00923 
00924 #endif
00925       
00926       // Write the Finite Element type of the var-th variable 
00927       // in this System
00928       {
00929         // set up the comment
00930         comment = "#     FE Family, Variable \"";
00931         std::sprintf(buf, "%s", this->variable_name(var).c_str());
00932         comment += buf;
00933         comment += "\", System \"";
00934         comment += this->name();
00935         comment += "\"";
00936       
00937         const FEType& type = this->variable_type(var);        
00938         int fam = static_cast<int>(type.family);              
00939         io.data (fam, comment.c_str());
00940 
00941 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
00942         
00943         comment = "#     Radial FE Family, Variable \"";
00944         std::sprintf(buf, "%s", this->variable_name(var).c_str());
00945         comment += buf;
00946         comment += "\", System \"";
00947         comment += this->name();
00948         comment += "\"";
00949       
00950         int radial_fam = static_cast<int>(type.radial_family);
00951         io.data (radial_fam, comment.c_str());  
00952         
00953         comment = "#     Infinite Mapping Type, Variable \"";
00954         std::sprintf(buf, "%s", this->variable_name(var).c_str());
00955         comment += buf;
00956         comment += "\", System \"";
00957         comment += this->name();
00958         comment += "\"";
00959 
00960         int i_map = static_cast<int>(type.inf_map);           
00961         io.data (i_map, comment.c_str());
00962 #endif
00963       }
00964     } // end of the variable loop
00965  
00966   // 8.) 
00967   // Write the number of additional vectors in the System.
00968   // If write_additional_data==false, then write zero for
00969   // the number of additional vectors.
00970   {       
00971     {
00972       // set up the comment
00973       comment = "# No. of Additional Vectors, System \"";
00974       comment += this->name();
00975       comment += "\"";
00976     
00977       unsigned int n_vectors = write_additional_data ? this->n_vectors () : 0;
00978       io.data (n_vectors, comment.c_str());
00979     }  
00980       
00981     if (write_additional_data)
00982       {
00983         std::map<std::string, NumericVector<Number>* >::const_iterator
00984           vec_pos = this->_vectors.begin();
00985         unsigned int cnt=0;
00986         
00987         for (; vec_pos != this->_vectors.end(); ++vec_pos)
00988           {
00989             // 9.)
00990             // write the name of the cnt-th additional vector
00991             comment =  "# Name of ";
00992             std::sprintf(buf, "%d", cnt++);
00993             comment += buf;
00994             comment += "th vector";
00995             std::string vec_name = vec_pos->first;
00996             
00997             io.data (vec_name, comment.c_str());
00998           }
00999       }
01000   }
01001 }

void System::write_parallel_data ( Xdr io,
const bool  write_additional_data 
) const

Writes additional data, namely vectors, for this System. This method may safely be called on a distributed-memory mesh. This method will create an individual file for each processor in the simulation where the local solution components for that processor will be stored.

This method implements the output of the vectors contained in this System object, embedded in the output of an EquationSystems<T_sys>.

9.) The global solution vector, re-ordered to be node-major (More on this later.)

for each additional vector in the object

10.) The global additional vector, re-ordered to be node-major (More on this later.)

Note that the actual IO is handled through the Xdr class (to be renamed later?) which provides a uniform interface to both the XDR (eXternal Data Representation) interface and standard ASCII output. Thus this one section of code will read XDR or ASCII files with no changes.

This method implements the output of the vectors contained in this System object, embedded in the output of an EquationSystems<T_sys>.

9.) The global solution vector, re-ordered to be node-major (More on this later.)

for each additional vector in the object

10.) The global additional vector, re-ordered to be node-major (More on this later.)

Note that the actual IO is handled through the Xdr class (to be renamed later?) which provides a uniform interface to both the XDR (eXternal Data Representation) interface and standard ASCII output. Thus this one section of code will read XDR or ASCII files with no changes.

Definition at line 1213 of file system_io.C.

References _vectors, Xdr::data(), get_mesh(), DofObject::invalid_id, n_vars(), name(), number(), solution, and Xdr::writing().

01215 {
01235   std::string comment;
01236   
01237   libmesh_assert (io.writing());
01238 
01239   std::vector<Number> io_buffer; io_buffer.reserve(this->solution->local_size());
01240 
01241   // build the ordered nodes and element maps.
01242   // when writing/reading parallel files we need to iterate
01243   // over our nodes/elements in order of increasing global id().
01244   // however, this is not guaranteed to be ordering we obtain
01245   // by using the node_iterators/element_iterators directly.
01246   // so build a set, sorted by id(), that provides the ordering.
01247   // further, for memory economy build the set but then transfer
01248   // its contents to vectors, which will be sorted.
01249   std::vector<const DofObject*> ordered_nodes, ordered_elements;
01250   {    
01251     std::set<const DofObject*, CompareDofObjectsByID>
01252       ordered_nodes_set (this->get_mesh().local_nodes_begin(),
01253                          this->get_mesh().local_nodes_end());
01254       
01255       ordered_nodes.insert(ordered_nodes.end(),
01256                            ordered_nodes_set.begin(),
01257                            ordered_nodes_set.end());
01258   }
01259   {
01260     std::set<const DofObject*, CompareDofObjectsByID>
01261       ordered_elements_set (this->get_mesh().local_elements_begin(),
01262                             this->get_mesh().local_elements_end());
01263       
01264       ordered_elements.insert(ordered_elements.end(),
01265                               ordered_elements_set.begin(),
01266                               ordered_elements_set.end());
01267   }
01268   
01269   const unsigned int sys_num = this->number();
01270   const unsigned int n_vars  = this->n_vars();
01271   
01272   // Loop over each variable and each node, and write out the value.
01273   for (unsigned int var=0; var<n_vars; var++)
01274     {
01275       // First write the node DOF values
01276       for (std::vector<const DofObject*>::const_iterator
01277              it = ordered_nodes.begin(); it != ordered_nodes.end(); ++it)      
01278         for (unsigned int comp=0; comp<(*it)->n_comp(sys_num, var); comp++)
01279           {
01280             //std::cout << "(*it)->id()=" << (*it)->id() << std::endl;
01281             libmesh_assert ((*it)->dof_number(sys_num, var, comp) !=
01282                     DofObject::invalid_id);
01283             
01284             io_buffer.push_back((*this->solution)((*it)->dof_number(sys_num, var, comp)));
01285           }
01286 
01287       // Then write the element DOF values
01288       for (std::vector<const DofObject*>::const_iterator
01289              it = ordered_elements.begin(); it != ordered_elements.end(); ++it)
01290         for (unsigned int comp=0; comp<(*it)->n_comp(sys_num, var); comp++)
01291           {
01292             libmesh_assert ((*it)->dof_number(sys_num, var, comp) !=
01293                     DofObject::invalid_id);
01294               
01295             io_buffer.push_back((*this->solution)((*it)->dof_number(sys_num, var, comp)));    
01296           }
01297     }
01298   
01299   // 9.)
01300   //
01301   // Actually write the reordered solution vector 
01302   // for the ith system to disk
01303   
01304   // set up the comment
01305   {
01306     comment = "# System \"";
01307     comment += this->name();
01308     comment += "\" Solution Vector";
01309   }
01310   
01311   io.data (io_buffer, comment.c_str());   
01312   
01313   // Only write additional vectors if wanted  
01314   if (write_additional_data)
01315     {     
01316       std::map<std::string, NumericVector<Number>* >::const_iterator
01317         pos = _vectors.begin();
01318   
01319       for(; pos != this->_vectors.end(); ++pos)
01320         {
01321           io_buffer.clear(); io_buffer.reserve( pos->second->local_size());
01322           
01323           // Loop over each variable and each node, and write out the value.
01324           for (unsigned int var=0; var<n_vars; var++)
01325             {
01326               // First write the node DOF values
01327               for (std::vector<const DofObject*>::const_iterator
01328                      it = ordered_nodes.begin(); it != ordered_nodes.end(); ++it)      
01329                 for (unsigned int comp=0; comp<(*it)->n_comp(sys_num, var); comp++)
01330                   {
01331                     libmesh_assert ((*it)->dof_number(sys_num, var, comp) !=
01332                             DofObject::invalid_id);
01333                       
01334                     io_buffer.push_back((*pos->second)((*it)->dof_number(sys_num, var, comp)));   
01335                   }
01336 
01337               // Then write the element DOF values
01338               for (std::vector<const DofObject*>::const_iterator
01339                      it = ordered_elements.begin(); it != ordered_elements.end(); ++it)
01340                 for (unsigned int comp=0; comp<(*it)->n_comp(sys_num, var); comp++)
01341                   {
01342                     libmesh_assert ((*it)->dof_number(sys_num, var, comp) !=
01343                             DofObject::invalid_id);
01344               
01345                     io_buffer.push_back((*pos->second)((*it)->dof_number(sys_num, var, comp)));
01346                   }
01347             }
01348           
01349           // 10.)
01350           //
01351           // Actually write the reordered additional vector 
01352           // for this system to disk
01353           
01354           // set up the comment
01355           {
01356             comment = "# System \"";
01357             comment += this->name(); 
01358             comment += "\" Additional Vector \"";
01359             comment += pos->first;
01360             comment += "\"";
01361           }
01362               
01363           io.data (io_buffer, comment.c_str());         
01364         }
01365     }
01366 }

template<typename iterator_type >
unsigned int System::write_serialized_blocked_dof_objects ( const NumericVector< Number > &  vec,
const unsigned int  var,
const unsigned int  n_objects,
const iterator_type  begin,
const iterator_type  end,
Xdr io 
) const [inline, private]

Writes an output vector to the stream io for a set of DofObjects. This method uses blocked output and is safe to call on a distributed memory-mesh.

Definition at line 1428 of file system_io.C.

References Xdr::data_stream(), NumericVector< T >::first_local_index(), MeshTools::Generation::Private::idx(), libMesh::invalid_uint, io_blksize, NumericVector< T >::last_local_index(), std::min(), libMesh::n_processors(), number(), and libMesh::processor_id().

Referenced by write_serialized_vector().

01434 {
01435   
01436   const unsigned int sys_num = this->number();
01437   
01438   unsigned int written_length=0;                       // The numer of values written.  This will be returned 
01439   std::vector<unsigned int> xfer_ids;                  // The global IDs and # of components for the local objects in the current block
01440   std::vector<Number>       xfer_vals;                 // The raw values for the local objects in the current block
01441   std::vector<std::vector<unsigned int> >              // The global ID and # of components received from each processor
01442     recv_ids (libMesh::n_processors());                //  for the current block
01443   std::vector<std::vector<Number> >                    // The raw values received from each processor
01444     recv_vals(libMesh::n_processors());                //  for the current block
01445   std::vector<std::vector<Number>::iterator>           // The next value on each processor for the current block
01446     val_iters;
01447   val_iters.reserve(libMesh::n_processors());
01448   std::vector<unsigned int> &idx_map     = xfer_ids;   // map to traverse entry-wise rather than processor-wise (renamed for notational convenience)
01449   std::vector<Number>       &output_vals = xfer_vals;  // The output buffer for the current block (renamed for notational convenience)
01450   
01451   //---------------------------------
01452   // Collect the values for all objects
01453   unsigned int first_object=0, last_object=0;
01454   
01455   for (unsigned int blk=0; last_object<n_objects; blk++)
01456     {
01457       //std::cout << "Writing object block " << blk << " for var " << var << std::endl;
01458       
01459       // Each processor should build up its transfer buffers for its
01460       // local objects in [first_object,last_object).
01461       first_object = blk*io_blksize;
01462       last_object  = std::min((blk+1)*io_blksize,n_objects);
01463           
01464       // Clear the transfer buffers for this block.
01465       xfer_ids.clear(); xfer_vals.clear();
01466       
01467       for (iterator_type it=begin; it!=end; ++it)
01468         if (((*it)->id() >= first_object) && // object in [first_object,last_object)
01469             ((*it)->id() <   last_object) &&
01470             (*it)->n_comp(sys_num,var)  )    // var has a nonzero # of components on this object
01471           {
01472             xfer_ids.push_back((*it)->id());
01473             xfer_ids.push_back((*it)->n_comp(sys_num, var));
01474             
01475             for (unsigned int comp=0; comp<(*it)->n_comp(sys_num, var); comp++)
01476               {
01477                 libmesh_assert ((*it)->dof_number(sys_num, var, comp) >= vec.first_local_index());
01478                 libmesh_assert ((*it)->dof_number(sys_num, var, comp) <  vec.last_local_index());
01479                 xfer_vals.push_back(vec((*it)->dof_number(sys_num, var, comp)));
01480               }
01481           }
01482 
01483       //-----------------------------------------
01484       // Send the transfer buffers to processor 0.
01485       
01486       // Get the size of the incoming buffers -- optionally
01487       // we could over-size the recv buffers based on
01488       // some maximum size to avoid these communications
01489       std::vector<unsigned int> ids_size, vals_size;
01490       const unsigned int my_ids_size  = xfer_ids.size();
01491       const unsigned int my_vals_size = xfer_vals.size();
01492       
01493       Parallel::gather (0, my_ids_size,  ids_size);
01494       Parallel::gather (0, my_vals_size, vals_size);
01495       
01496       // Note that we will actually send/receive to ourself if we are
01497       // processor 0, so let's use nonblocking receives.
01498       std::vector<Parallel::request>
01499         id_request_handles(libMesh::n_processors()),
01500         val_request_handles(libMesh::n_processors());
01501       
01502 #ifdef LIBMESH_HAVE_MPI
01503       const unsigned int id_tag=0, val_tag=1;
01504       
01505       // Post the receives -- do this on processor 0 only.
01506       if (libMesh::processor_id() == 0)
01507         for (unsigned int pid=0; pid<libMesh::n_processors(); pid++)
01508           {
01509             recv_ids[pid].resize(ids_size[pid]);
01510             recv_vals[pid].resize(vals_size[pid]);
01511             
01512             Parallel::nonblocking_receive (pid, recv_ids[pid],
01513                                            id_request_handles[pid],
01514                                            id_tag);
01515             Parallel::nonblocking_receive (pid, recv_vals[pid],
01516                                            val_request_handles[pid],
01517                                            val_tag);
01518           }
01519       
01520       // Send -- do this on all processors.
01521       Parallel::send(0, xfer_ids,  id_tag);
01522       Parallel::send(0, xfer_vals, val_tag);
01523 #else
01524       // On one processor there's nothing to send
01525       recv_ids[0] = xfer_ids;
01526       recv_vals[0] = xfer_vals;
01527 #endif
01528       
01529       // -------------------------------------------------------
01530       // Receive the messages and write the output on processor 0.
01531       if (libMesh::processor_id() == 0)
01532         {
01533           // Wait for all the receives to complete. We have no
01534           // need for the statuses since we already know the
01535           // buffer sizes.
01536           Parallel::wait (id_request_handles);
01537           Parallel::wait (val_request_handles);
01538           
01539           // Write the values in this block.
01540           unsigned int tot_id_size=0, tot_val_size=0;
01541           val_iters.clear();
01542           for (unsigned int pid=0; pid<libMesh::n_processors(); pid++)
01543             {
01544               tot_id_size  += recv_ids[pid].size();                 
01545               tot_val_size += recv_vals[pid].size();
01546               val_iters.push_back(recv_vals[pid].begin());
01547             }
01548           
01549           libmesh_assert (tot_id_size <= 2*std::min(io_blksize,n_objects));
01550           
01551           // Create a map to avoid searching.  This will allow us to
01552           // traverse the received values in [first_object,last_object) order.
01553           idx_map.resize(3*io_blksize); std::fill (idx_map.begin(), idx_map.end(), libMesh::invalid_uint);
01554           for (unsigned int pid=0; pid<libMesh::n_processors(); pid++)
01555             for (unsigned int idx=0; idx<recv_ids[pid].size(); idx+=2)
01556               {
01557                 const unsigned int local_idx = recv_ids[pid][idx+0]-first_object;
01558                 libmesh_assert (local_idx < std::min(io_blksize,n_objects));
01559                 const unsigned int n_comp    = recv_ids[pid][idx+1];
01560                 
01561                 idx_map[3*local_idx+0] = pid;
01562                 idx_map[3*local_idx+1] = n_comp;
01563                 idx_map[3*local_idx+2] = std::distance(recv_vals[pid].begin(), val_iters[pid]);
01564                 val_iters[pid] += n_comp;
01565               }
01566 
01567           output_vals.clear(); output_vals.reserve (tot_val_size);
01568           for (unsigned int idx=0; idx<idx_map.size(); idx+=3)
01569             if (idx_map[idx] != libMesh::invalid_uint) // this could happen when a local object
01570               {                                        // has no components for the current variable
01571                 const unsigned int pid       = idx_map[idx+0];
01572                 const unsigned int n_comp    = idx_map[idx+1];
01573                 const unsigned int first_pos = idx_map[idx+2];
01574                 
01575                 for (unsigned int comp=0; comp<n_comp; comp++)
01576                   {
01577                     libmesh_assert (first_pos + comp < recv_vals[pid].size());
01578                     output_vals.push_back(recv_vals[pid][first_pos + comp]);
01579                   }
01580               }
01581           libmesh_assert (output_vals.size() == tot_val_size);
01582           
01583           // write the stream
01584           io.data_stream (output_vals.empty() ? NULL : &output_vals[0], output_vals.size());
01585           written_length += output_vals.size();
01586         } // end processor 0 conditional block    
01587     } // end object block loop
01588 
01589   return written_length;
01590 }

void System::write_serialized_data ( Xdr io,
const bool  write_additional_data = true 
) const

Writes additional data, namely vectors, for this System. This method may safely be called on a distributed-memory mesh.

This method implements the output of the vectors contained in this System object, embedded in the output of an EquationSystems<T_sys>.

9.) The global solution vector, re-ordered to be node-major (More on this later.)

for each additional vector in the object

10.) The global additional vector, re-ordered to be node-major (More on this later.)

Definition at line 1370 of file system_io.C.

References _vectors, Xdr::comment(), name(), libMesh::processor_id(), solution, and write_serialized_vector().

01372 {
01386   parallel_only();
01387   std::string comment;
01388 
01389   this->write_serialized_vector(io, *this->solution); 
01390 
01391   // set up the comment
01392   if (libMesh::processor_id() == 0)
01393     {
01394       comment = "# System \"";
01395       comment += this->name();
01396       comment += "\" Solution Vector";
01397 
01398       io.comment (comment);
01399     }
01400 
01401   // Only write additional vectors if wanted  
01402   if (write_additional_data)
01403     {     
01404       std::map<std::string, NumericVector<Number>* >::const_iterator
01405         pos = _vectors.begin();
01406   
01407       for(; pos != this->_vectors.end(); ++pos)
01408         {
01409           this->write_serialized_vector(io, *pos->second);
01410 
01411           // set up the comment
01412           if (libMesh::processor_id() == 0)
01413             {
01414               comment = "# System \"";
01415               comment += this->name(); 
01416               comment += "\" Additional Vector \"";
01417               comment += pos->first;
01418               comment += "\"";
01419               io.comment (comment);       
01420             }
01421         }
01422     }
01423 }

void System::write_serialized_vector ( Xdr io,
const NumericVector< Number > &  vec 
) const [private]

Writes a vector for this System. This method may safely be called on a distributed-memory mesh.

Definition at line 1594 of file system_io.C.

References Xdr::data(), get_mesh(), io_blksize, MeshTools::n_elem(), n_nodes, n_vars(), libMesh::processor_id(), NumericVector< T >::size(), write_serialized_blocked_dof_objects(), and Xdr::writing().

Referenced by write_serialized_data().

01595 {
01596   parallel_only();
01597   
01598   // If this is not the same on all processors we're in trouble!
01599   libmesh_assert (Parallel::verify(io_blksize));
01600   libmesh_assert (io.writing());
01601   
01602   unsigned int vec_length = vec.size();
01603   if (libMesh::processor_id() == 0) io.data (vec_length, "# vector length");
01604   
01605   unsigned int written_length = 0;
01606   
01607   // Loop over each variable in the system, and then each node/element in the mesh.
01608   for (unsigned int var=0; var<this->n_vars(); var++)
01609     {
01610       //---------------------------------
01611       // Collect the values for all nodes
01612       written_length +=
01613         this->write_serialized_blocked_dof_objects (vec,
01614                                                     var,
01615                                                     this->get_mesh().n_nodes(),
01616                                                     this->get_mesh().local_nodes_begin(),
01617                                                     this->get_mesh().local_nodes_end(),
01618                                                     io);
01619       
01620       //------------------------------------
01621       // Collect the values for all elements
01622       written_length +=
01623         this->write_serialized_blocked_dof_objects (vec,
01624                                                     var,
01625                                                     this->get_mesh().n_elem(),
01626                                                     this->get_mesh().local_elements_begin(),
01627                                                     this->get_mesh().local_elements_end(),
01628                                                     io);
01629     } // end variable loop
01630 
01631   if (libMesh::processor_id() == 0)
01632     libmesh_assert(written_length == vec_length);
01633 }

void System::zero_variable ( NumericVector< Number > &  v,
unsigned int  var_num 
) const

Zeroes all dofs in v that correspond to variable number var_num.

Definition at line 689 of file system.C.

References MeshBase::active_local_elements_begin(), MeshBase::active_local_elements_end(), DofObject::dof_number(), get_mesh(), MeshBase::local_nodes_begin(), MeshBase::local_nodes_end(), mesh, DofObject::n_comp(), n_vars(), number(), and NumericVector< T >::set().

00690 {
00691   /* Make sure the call makes sense.  */
00692   libmesh_assert(var_num<this->n_vars());
00693 
00694   /* Get a reference to the mesh.  */
00695   const MeshBase& mesh = this->get_mesh();
00696 
00697   /* Check which system we are.  */
00698   const unsigned int sys_num = this->number();
00699 
00700   /* Loop over nodes.  */
00701   {
00702     MeshBase::const_node_iterator it = mesh.local_nodes_begin();
00703     const MeshBase::const_node_iterator end_it = mesh.local_nodes_end(); 
00704     for ( ; it != end_it; ++it)
00705       {    
00706         const Node* node = *it;
00707         unsigned int n_comp = node->n_comp(sys_num,var_num);
00708         for(unsigned int i=0; i<n_comp; i++)
00709           {
00710             const unsigned int index = node->dof_number(sys_num,var_num,i);
00711             v.set(index,0.0);
00712           }
00713       }
00714   }
00715 
00716   /* Loop over elements.  */
00717   {
00718     MeshBase::const_element_iterator it = mesh.active_local_elements_begin();
00719     const MeshBase::const_element_iterator end_it = mesh.active_local_elements_end(); 
00720     for ( ; it != end_it; ++it)
00721       {    
00722         const Elem* elem = *it;
00723         unsigned int n_comp = elem->n_comp(sys_num,var_num);
00724         for(unsigned int i=0; i<n_comp; i++)
00725           {
00726             const unsigned int index = elem->dof_number(sys_num,var_num,i);
00727             v.set(index,0.0);
00728           }
00729       }
00730   }
00731 }


Member Data Documentation

bool System::_active [private]

Flag stating if the system is active or not.

Definition at line 837 of file system.h.

Referenced by activate(), active(), and deactivate().

This flag is used only when *reading* in a system from file. Based on the system header, it keeps track of whether or not additional vectors were actually written for this file.

Definition at line 870 of file system.h.

Referenced by read_header(), and read_legacy_data().

void(* System::_assemble_system)(EquationSystems &es, const std::string &name) [private]

Function that assembles the system.

Referenced by attach_assemble_function(), user_assembly(), and ~System().

bool System::_can_add_vectors [private]

true when additional vectors may still be added, false otherwise.

Definition at line 863 of file system.h.

Referenced by add_vector(), clear(), compare(), init_data(), and read_header().

void(* System::_constrain_system)(EquationSystems &es, const std::string &name) [private]

Function to impose constraints.

Referenced by attach_constraint_function(), and user_constrain().

Data structure describing the relationship between nodes, variables, etc... and degrees of freedom.

Definition at line 799 of file system.h.

Referenced by add_variable(), calculate_norm(), clear(), get_dof_map(), init_data(), n_constrained_dofs(), n_dofs(), n_local_dofs(), restrict_vectors(), and update().

Constant reference to the EquationSystems object used for the simulation.

Definition at line 805 of file system.h.

Referenced by get_equation_systems(), user_assembly(), user_constrain(), user_initialization(), and user_QOI().

void(* System::_init_system)(EquationSystems &es, const std::string &name) [private]

Function that initializes the system.

Referenced by attach_init_function(), user_initialization(), and ~System().

MeshBase& System::_mesh [private]

Constant reference to the mesh data structure used for the simulation.

Definition at line 811 of file system.h.

Referenced by get_mesh().

Threads::spin_mutex ReferenceCounter::_mutex [static, protected, inherited]

Mutual exclusion object to enable thread-safe reference counting.

Definition at line 123 of file reference_counter.h.

Threads::atomic< unsigned int > ReferenceCounter::_n_objects [static, protected, inherited]

The number of objects. Print the reference count information when the number returns to 0.

Definition at line 118 of file reference_counter.h.

Referenced by ReferenceCounter::n_objects(), ReferenceCounter::ReferenceCounter(), and ReferenceCounter::~ReferenceCounter().

void(* System::_qoi_evaluate_system)(EquationSystems &es, const std::string &name) [private]

Function to evaluate quantity of interest

Referenced by attach_QOI_function(), and user_QOI().

Holds true if the solution vector should be projected onto a changed grid, false if it should be zeroed. This is true by default.

Definition at line 858 of file system.h.

Referenced by project_solution_on_reinit(), and restrict_vectors().

const std::string System::_sys_name [private]

A name associated with this system.

Definition at line 816 of file system.h.

Referenced by compare(), and name().

const unsigned int System::_sys_number [private]

The number associated with this system

Definition at line 821 of file system.h.

Referenced by number().

std::map<std::string, unsigned short int> System::_variable_numbers [private]

The variable numbers corresponding to user-specified names, useful for name-based lookups.

Definition at line 832 of file system.h.

Referenced by add_variable(), clear(), has_variable(), and variable_number().

std::vector<System::Variable> System::_variables [private]

The Variables in this System.

Definition at line 826 of file system.h.

Referenced by add_variable(), clear(), n_vars(), variable(), variable_name(), variable_number(), and variable_type().

std::map<std::string, bool> System::_vector_projections [private]

Holds true if a vector by that name should be projected onto a changed grid, false if it should be zeroed.

Definition at line 851 of file system.h.

Referenced by add_vector(), clear(), and restrict_vectors().

std::map<std::string, NumericVector<Number>* > System::_vectors [private]

Some systems need an arbitrary number of vectors. This map allows names to be associated with arbitrary vectors. All the vectors in this map will be distributed in the same way as the solution vector.

Definition at line 845 of file system.h.

Referenced by add_vector(), clear(), compare(), get_vector(), have_vector(), init_data(), n_vectors(), read_legacy_data(), read_parallel_data(), read_serialized_data(), restrict_vectors(), vectors_begin(), vectors_end(), write_header(), write_parallel_data(), and write_serialized_data().

Flag which tells the system to whether or not to call the user assembly function during each call to solve(). By default, every call to solve() begins with a call to the user assemble, so this flag is true. (For explicit systems, "solving" the system occurs during the assembly step, so this flag is always true for explicit systems.)

You will only want to set this to false if you need direct control over when the system is assembled, and are willing to track the state of its assembly yourself. An example of such a case is an implicit system with multiple right hand sides. In this instance, a single assembly would likely be followed with multiple calls to solve.

The frequency system and Newmark system have their own versions of this flag, called _finished_assemble, which might be able to be replaced with this more general concept.

Definition at line 657 of file system.h.

Referenced by NonlinearImplicitSystem::adjoint_solve(), LinearImplicitSystem::adjoint_solve(), LinearImplicitSystem::solve(), and EigenSystem::solve().

All the values I need to compute my contribution to the simulation at hand. Think of this as the current solution with any ghost values needed from other processors. This vector is necessarily larger than the solution vector in the case of a parallel simulation. The update() member is used to synchronize the contents of the solution and current_local_solution vectors.

Definition at line 684 of file system.h.

Referenced by NonlinearImplicitSystem::adjoint_solve(), clear(), Problem_Interface::computeF(), current_solution(), ExactErrorEstimator::estimate_error(), init_data(), project_solution(), re_update(), reinit(), restrict_vectors(), and update().


The documentation for this class was generated from the following files:

Site Created By: libMesh Developers
Last modified: May 26 2009 03:54:50.

Hosted By:
SourceForge.net Logo