$extrastylesheet
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