$extrastylesheet
diff_context.C
Go to the documentation of this file.
00001 // The libMesh Finite Element Library.
00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
00003 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either
00007 // version 2.1 of the License, or (at your option) any later version.
00008 
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // Lesser General Public License for more details.
00013 
00014 // You should have received a copy of the GNU Lesser General Public
00015 // License along with this library; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 
00019 #include "libmesh/diff_context.h"
00020 #include "libmesh/diff_system.h"
00021 
00022 namespace libMesh
00023 {
00024 
00025 
00026 
00027 DiffContext::DiffContext (const System& sys) :
00028   time(sys.time),
00029   system_time(sys.time),
00030   elem_solution_derivative(1.),
00031   elem_solution_rate_derivative(1.),
00032   fixed_solution_derivative(0.),
00033   _dof_indices_var(sys.n_vars()),
00034   _deltat(NULL),
00035   _system(sys),
00036   _is_adjoint(false)
00037 {
00038   // Finally initialize solution/residual/jacobian data structures
00039   unsigned int nv = sys.n_vars();
00040 
00041   _elem_subsolutions.reserve(nv);
00042   _elem_subresiduals.reserve(nv);
00043   _elem_subjacobians.resize(nv);
00044   _elem_subsolution_rates.reserve(nv);
00045   if (sys.use_fixed_solution)
00046     _elem_fixed_subsolutions.reserve(nv);
00047 
00048   // If the user resizes sys.qoi, it will invalidate us
00049   std::size_t n_qoi = sys.qoi.size();
00050   _elem_qoi.resize(n_qoi);
00051   _elem_qoi_derivative.resize(n_qoi);
00052   _elem_qoi_subderivatives.resize(n_qoi);
00053   for (std::size_t q=0; q != n_qoi; ++q)
00054     _elem_qoi_subderivatives[q].reserve(nv);
00055 
00056   for (unsigned int i=0; i != nv; ++i)
00057     {
00058       _elem_subsolutions.push_back(new DenseSubVector<Number>(_elem_solution));
00059       _elem_subresiduals.push_back(new DenseSubVector<Number>(_elem_residual));
00060       for (std::size_t q=0; q != n_qoi; ++q)
00061         _elem_qoi_subderivatives[q].push_back(new DenseSubVector<Number>(_elem_qoi_derivative[q]));
00062       _elem_subjacobians[i].reserve(nv);
00063       _elem_subsolution_rates.push_back(new DenseSubVector<Number>(_elem_solution_rate));
00064 
00065       if (sys.use_fixed_solution)
00066         _elem_fixed_subsolutions.push_back
00067           (new DenseSubVector<Number>(_elem_fixed_solution));
00068 
00069       for (unsigned int j=0; j != nv; ++j)
00070         {
00071           _elem_subjacobians[i].push_back
00072             (new DenseSubMatrix<Number>(_elem_jacobian));
00073         }
00074     }
00075 }
00076 
00077 
00078 
00079 DiffContext::~DiffContext ()
00080 {
00081   for (std::size_t i=0; i != _elem_subsolutions.size(); ++i)
00082     {
00083       delete _elem_subsolutions[i];
00084       delete _elem_subresiduals[i];
00085       for (std::size_t q=0; q != _elem_qoi_subderivatives.size(); ++q)
00086         delete _elem_qoi_subderivatives[q][i];
00087       delete _elem_subsolution_rates[i];
00088       if (!_elem_fixed_subsolutions.empty())
00089         delete _elem_fixed_subsolutions[i];
00090 
00091       for (std::size_t j=0; j != _elem_subjacobians[i].size(); ++j)
00092         delete _elem_subjacobians[i][j];
00093     }
00094 
00095   // We also need to delete all the DenseSubVectors from the localized_vectors map
00096   // localized_vectors iterators
00097   std::map<const NumericVector<Number>*, std::pair<DenseVector<Number>, std::vector<DenseSubVector<Number>*> > >::iterator localized_vectors_it = _localized_vectors.begin();
00098   std::map<const NumericVector<Number>*, std::pair<DenseVector<Number>, std::vector<DenseSubVector<Number>*> > >::iterator localized_vectors_end = _localized_vectors.end();
00099 
00100   // Loop over every localized_vector
00101   for(; localized_vectors_it != localized_vectors_end; ++localized_vectors_it)
00102     {
00103       // Grab the DenseSubVector to be deleted
00104       std::vector<DenseSubVector<Number>* >&  localized_vector_dsv = localized_vectors_it->second.second;
00105 
00106       // Loop over that vector and delete each entry
00107       for(std::size_t i=0; i != localized_vector_dsv.size(); ++i)
00108         delete localized_vector_dsv[i];
00109     }
00110 }
00111 
00112 
00113 void DiffContext::set_deltat_pointer(Real* dt)
00114 {
00115   // We may actually want to be able to set this pointer to NULL, so
00116   // don't report an error for that.
00117   _deltat = dt;
00118 }
00119 
00120 
00121 Real DiffContext::get_deltat_value()
00122 {
00123   libmesh_assert(_deltat);
00124 
00125   return *_deltat;
00126 }
00127 
00128 
00129 void DiffContext::add_localized_vector (NumericVector<Number> & localized_vector, const System & sys)
00130 {
00131   // Make an empty pair keyed with a reference to this _localized_vector
00132   _localized_vectors[&localized_vector] = std::make_pair(DenseVector<Number>(), std::vector<DenseSubVector<Number>*>());
00133 
00134   unsigned int nv = sys.n_vars();
00135 
00136   _localized_vectors[&localized_vector].second.reserve(nv);
00137 
00138   // Fill the DenseSubVector with nv copies of DenseVector
00139   for(unsigned int i=0; i != nv; ++i)
00140     _localized_vectors[&localized_vector].second.push_back(new DenseSubVector<Number>(_localized_vectors[&localized_vector].first));
00141 }
00142 
00143 
00144 DenseVector<Number>& DiffContext::get_localized_vector (const NumericVector<Number> & localized_vector)
00145 {
00146   return _localized_vectors[&localized_vector].first;
00147 }
00148 
00149 
00150 const DenseVector<Number>& DiffContext::get_localized_vector (const NumericVector<Number> & localized_vector) const
00151 {
00152   std::map<const NumericVector<Number>*, std::pair<DenseVector<Number>, std::vector<DenseSubVector<Number>*> > >::const_iterator
00153     localized_vectors_it = _localized_vectors.find(&localized_vector);
00154   libmesh_assert(localized_vectors_it != _localized_vectors.end());
00155   return localized_vectors_it->second.first;
00156 }
00157 
00158 
00159 DenseSubVector<Number>& DiffContext::get_localized_subvector (const NumericVector<Number> & localized_vector, unsigned int var)
00160 {
00161   return *_localized_vectors[&localized_vector].second[var];
00162 }
00163 
00164 
00165 const DenseSubVector<Number>& DiffContext::get_localized_subvector (const NumericVector<Number> & localized_vector, unsigned int var) const
00166 {
00167   std::map<const NumericVector<Number>*, std::pair<DenseVector<Number>, std::vector<DenseSubVector<Number>*> > >::const_iterator
00168     localized_vectors_it = _localized_vectors.find(&localized_vector);
00169   libmesh_assert(localized_vectors_it != _localized_vectors.end());
00170   return *localized_vectors_it->second.second[var];
00171 }
00172 
00173 } // namespace libMesh