1 // @HEADER 2 // ************************************************************************ 3 // 4 // Rapid Optimization Library (ROL) Package 5 // Copyright (2014) Sandia Corporation 6 // 7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 8 // license for use of this work by or on behalf of the U.S. Government. 9 // 10 // Redistribution and use in source and binary forms, with or without 11 // modification, are permitted provided that the following conditions are 12 // met: 13 // 14 // 1. Redistributions of source code must retain the above copyright 15 // notice, this list of conditions and the following disclaimer. 16 // 17 // 2. Redistributions in binary form must reproduce the above copyright 18 // notice, this list of conditions and the following disclaimer in the 19 // documentation and/or other materials provided with the distribution. 20 // 21 // 3. Neither the name of the Corporation nor the names of the 22 // contributors may be used to endorse or promote products derived from 23 // this software without specific prior written permission. 24 // 25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 // 37 // Questions? Contact lead developers: 38 // Drew Kouri (dpkouri@sandia.gov) and 39 // Denis Ridzal (dridzal@sandia.gov) 40 // 41 // ************************************************************************ 42 // @HEADER 43 44 45 #ifndef ROL_PDEOPT_ELASTICITYSIMP_OPERATORS_H 46 #define ROL_PDEOPT_ELASTICITYSIMP_OPERATORS_H 47 48 #include "Intrepid_HGRAD_QUAD_C2_FEM.hpp" 49 #include "Intrepid_HGRAD_QUAD_C1_FEM.hpp" 50 #include "../TOOLS/elasticitySIMP.hpp" 51 52 template<class Real> 53 class ElasticitySIMPOperators : public ElasticitySIMP <Real> { 54 private: 55 using GO = typename Tpetra::Map<>::global_ordinal_type; 56 57 Real volFrac_; 58 59 public: 60 ElasticitySIMPOperators(const ROL::Ptr<const Teuchos::Comm<int>> & comm,const Teuchos::RCP<Teuchos::ParameterList> & parlist,const ROL::Ptr<std::ostream> & outStream)61 ElasticitySIMPOperators(const ROL::Ptr<const Teuchos::Comm<int> > &comm, 62 const Teuchos::RCP<Teuchos::ParameterList> &parlist, 63 const ROL::Ptr<std::ostream> &outStream) { 64 ElasticitySIMPOperators_Initialize(comm, parlist, outStream); 65 this->SetSIMPParallelStructure(); 66 this->SetUpLocalIntrepidArrays(); 67 this->ComputeLocalSystemMats(true); 68 //Setup DBC information, do not specify any bc sides, use coordinates to determine the BC instead 69 std::vector<GO> dbc_side {}; 70 this->SetUpMyDBCInfo(true, dbc_side); 71 this->process_loading_information(parlist); 72 //With new modification on boundary traction, ComputeLocalForceVec should go after SetUpMyBCInfo and process_loading_information 73 //this->AssembleSystemGraph(); 74 this->AssembleSystemGraph(); 75 this->AssembleSystemMats(); 76 this->ComputeLocalForceVec(); 77 this->AssembleRHSVector(); 78 this->EnforceDBC(); 79 this->ConstructSolvers(); 80 } 81 ElasticitySIMPOperators_Initialize(const ROL::Ptr<const Teuchos::Comm<int>> & comm,const Teuchos::RCP<Teuchos::ParameterList> & parlist,const ROL::Ptr<std::ostream> & outStream)82 void ElasticitySIMPOperators_Initialize(const ROL::Ptr<const Teuchos::Comm<int> > &comm, 83 const Teuchos::RCP<Teuchos::ParameterList> &parlist, 84 const ROL::Ptr<std::ostream> &outStream) { 85 ElasticitySIMP<Real>::ElasticitySIMP_Initialize(comm, parlist, outStream); 86 volFrac_ = parlist->sublist("ElasticityTopoOpt").get<Real>("Volume Fraction"); 87 this->initDensity_ = volFrac_; 88 } 89 90 // construct solvers with new material constructSolverWithNewMaterial(void)91 void constructSolverWithNewMaterial(void) { 92 bool ifInit = false; 93 { 94 #ifdef ROL_TIMERS 95 Teuchos::TimeMonitor LocalTimer(*SolverUpdateTime_example_PDEOPT_TOOLS_PDEFEM_GLOB); 96 #endif 97 this->ComputeLocalSystemMats(ifInit); 98 this->AssembleSystemMats(); 99 this->MatrixRemoveDBC(); 100 } 101 this->ConstructSolvers(); 102 } 103 // 104 getPosCell(void) const105 ROL::Ptr<Intrepid::FieldContainer<int> > getPosCell(void) const { 106 return this->meshMgr_->getPosCell(); 107 } 108 ApplyMatAToVec(ROL::Ptr<Tpetra::MultiVector<>> & Ju,const ROL::Ptr<const Tpetra::MultiVector<>> & u)109 void ApplyMatAToVec(ROL::Ptr<Tpetra::MultiVector<> > &Ju, 110 const ROL::Ptr<const Tpetra::MultiVector<> > &u) { 111 this->matA_dirichlet_->apply(*u, *Ju); 112 } 113 ApplyJacobian1ToVec(ROL::Ptr<Tpetra::MultiVector<>> & Ju,const ROL::Ptr<const Tpetra::MultiVector<>> & u)114 void ApplyJacobian1ToVec(ROL::Ptr<Tpetra::MultiVector<> > &Ju, 115 const ROL::Ptr<const Tpetra::MultiVector<> > &u) { 116 #ifdef ROL_TIMERS 117 Teuchos::TimeMonitor LocalTimer(*ConstraintDerivativeTime_example_PDEOPT_TOOLS_PDEFEM_GLOB); 118 #endif 119 this->matA_dirichlet_->apply(*u, *Ju); 120 // Jv is myUniqueMap_ 121 // u is myUniqueMap_ 122 // v should be myCellMap_ 123 // 124 /* 125 ROL::Ptr<Tpetra::MultiVector<> > Ju_overlap = ROL::makePtr<Tpetra::MultiVector<>>(this->myOverlapMap_, 1, true); 126 ROL::Ptr<Tpetra::MultiVector<> > u_overlap = ROL::makePtr<Tpetra::MultiVector<>>(this->myOverlapMap_, 1, true); 127 Tpetra::Import<> importer(u->getMap(), u_overlap->getMap()); 128 u_overlap->doImport(*u, importer, Tpetra::REPLACE); 129 //simply apply matrix to a vector, no need to apply EBC to the vec 130 //this-> ApplyBCToVec (u_overlap); 131 Teuchos::ArrayRCP<const Real> uData = u_overlap->get1dView(); 132 133 Real SIMPScale(0), sum(0), zero(0); 134 Intrepid::FieldContainer<Real> localDisp(this->numLocalDofs_); 135 136 for(int i=0; i<this->numCells_; i++) { 137 SIMPScale = this->SIMPmaterial_[i]->getSIMPScaleFactor(); 138 localDisp.initialize(zero); 139 for(int j=0; j<this->numLocalDofs_; j++) { 140 localDisp(j) = uData[u_overlap->getMap()->getLocalElement(this->cellDofs_(this->myCellIds_[i], j))]; 141 } 142 for(int j=0; j<this->numLocalDofs_; j++) { 143 if(this->check_myGlobalDof_on_boundary(this->cellDofs_(this->myCellIds_[i],j))) { 144 Ju_overlap -> replaceGlobalValue(this->cellDofs_(this->myCellIds_[i], j), 0, localDisp(j)); 145 } 146 else { 147 sum = zero; 148 for(int k=0; k<this->numLocalDofs_; k++) { 149 if( !this->check_myGlobalDof_on_boundary(this->cellDofs_(this->myCellIds_[i],k)) ) { 150 sum += SIMPScale * (*this->gradgradMats0_)(i, j, k) * localDisp(k); 151 } 152 } 153 Ju_overlap -> sumIntoGlobalValue(this->cellDofs_(this->myCellIds_[i], j), 0, sum); 154 } 155 } 156 } 157 158 Tpetra::Export<> exporter(Ju_overlap->getMap(), Ju->getMap()); 159 //Ju->doExport(*Ju_overlap, exporter, Tpetra::REPLACE); 160 Ju->doExport(*Ju_overlap, exporter, Tpetra::ADD); 161 */ 162 } 163 ApplyInverseJacobian1ToVec(ROL::Ptr<Tpetra::MultiVector<>> & InvJu,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const bool ifTrans)164 void ApplyInverseJacobian1ToVec(ROL::Ptr<Tpetra::MultiVector<> > &InvJu, 165 const ROL::Ptr<const Tpetra::MultiVector<> > &u, 166 const bool ifTrans) { 167 //Ju is matA->getDomainMap(); 168 #ifdef ROL_TIMERS 169 Teuchos::TimeMonitor LocalTimer(*LUSubstitutionTime_example_PDEOPT_TOOLS_PDEFEM_GLOB); 170 #endif 171 this->getSolver(ifTrans)->setB(u); 172 this->getSolver(ifTrans)->setX(InvJu); 173 this->getSolver(ifTrans)->solve(); 174 } 175 ApplyJacobian2ToVec(ROL::Ptr<Tpetra::MultiVector<>> & Jv,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & v)176 void ApplyJacobian2ToVec(ROL::Ptr<Tpetra::MultiVector<> > &Jv, 177 const ROL::Ptr<const Tpetra::MultiVector<> > &u, 178 const ROL::Ptr<const Tpetra::MultiVector<> > &v) { 179 // Jv is myUniqueMap_ 180 // u is myUniqueMap_ 181 // v should be myCellMap_ 182 // 183 #ifdef ROL_TIMERS 184 Teuchos::TimeMonitor LocalTimer(*ConstraintDerivativeTime_example_PDEOPT_TOOLS_PDEFEM_GLOB); 185 #endif 186 ROL::Ptr<Tpetra::MultiVector<> > Jv_overlap = ROL::makePtr<Tpetra::MultiVector<>>(this->myOverlapMap_, 1, true); 187 ROL::Ptr<Tpetra::MultiVector<> > u_overlap = ROL::makePtr<Tpetra::MultiVector<>>(this->myOverlapMap_, 1, true); 188 Tpetra::Import<> importer(u->getMap(), u_overlap->getMap()); 189 u_overlap->doImport(*u, importer, Tpetra::REPLACE); 190 //apply BC here, KU 191 this->ApplyBCToVec (u_overlap); 192 Teuchos::ArrayRCP<const Real> uData = u_overlap->get1dView(); 193 194 ROL::Ptr<Tpetra::MultiVector<> > v_local = ROL::makePtr<Tpetra::MultiVector<>>(this->myCellMap_, 1, true); 195 Tpetra::Export<> exporter1(v->getMap(), this->myCellMap_); 196 v_local->doExport(*v, exporter1, Tpetra::REPLACE); 197 Teuchos::ArrayRCP<const Real> vData = v_local->get1dView(); 198 199 Real SIMPDScale(0), localV(0), sum(0), zero(0); 200 Intrepid::FieldContainer<Real> localDisp(this->numLocalDofs_); 201 202 for(int i=0; i<this->numCells_; i++) { 203 SIMPDScale = this->SIMPmaterial_[i]->getSIMPFirstDerivativeScaleFactor(); 204 localV = vData[v_local->getMap()->getLocalElement(this->myCellIds_[i])]; 205 206 localDisp.initialize(zero); 207 for(int j=0; j<this->numLocalDofs_; j++) { 208 localDisp(j) = uData[u_overlap->getMap()->getLocalElement(this->cellDofs_(this->myCellIds_[i], j))]; 209 } 210 211 for(int j=0; j<this->numLocalDofs_; j++) { 212 if(this->check_myGlobalDof_on_boundary(this->cellDofs_(this->myCellIds_[i],j))) { 213 Jv_overlap -> replaceGlobalValue(this->cellDofs_(this->myCellIds_[i], j), 0, localDisp(j)); 214 } 215 else { 216 sum = zero; 217 for(int k=0; k<this->numLocalDofs_; k++) { 218 if( !this->check_myGlobalDof_on_boundary(this->cellDofs_(this->myCellIds_[i],k)) ) { 219 sum += localV * SIMPDScale * (*this->gradgradMats0_)(i, j, k) * localDisp(k); 220 } 221 } 222 Jv_overlap -> sumIntoGlobalValue(this->cellDofs_(this->myCellIds_[i], j), 0, sum); 223 } 224 } 225 } 226 Tpetra::Export<> exporter2(Jv_overlap->getMap(), Jv->getMap()); 227 //Jv->doExport(*Jv_overlap, exporter2, Tpetra::REPLACE); 228 Jv->doExport(*Jv_overlap, exporter2, Tpetra::ADD); 229 } 230 ApplyAdjointJacobian2ToVec(ROL::Ptr<Tpetra::MultiVector<>> & Jv,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & v)231 void ApplyAdjointJacobian2ToVec (ROL::Ptr<Tpetra::MultiVector<> > &Jv, 232 const ROL::Ptr<const Tpetra::MultiVector<> > &u, 233 const ROL::Ptr<const Tpetra::MultiVector<> > &v) { 234 // Jv is myCellMap_ 235 // u should be myUniqueMap_ 236 // v should be myUniqueMap_ 237 // 238 #ifdef ROL_TIMERS 239 Teuchos::TimeMonitor LocalTimer(*ConstraintDerivativeTime_example_PDEOPT_TOOLS_PDEFEM_GLOB); 240 #endif 241 ROL::Ptr<Tpetra::MultiVector<> > u_overlap = ROL::makePtr<Tpetra::MultiVector<>>(this->myOverlapMap_, 1, true); 242 Tpetra::Import<> importer1(u->getMap(), u_overlap->getMap()); 243 u_overlap->doImport(*u, importer1, Tpetra::REPLACE); 244 //only apply BC to u 245 this->ApplyBCToVec (u_overlap); 246 Teuchos::ArrayRCP<const Real> uData = u_overlap->get1dView(); 247 248 ROL::Ptr<Tpetra::MultiVector<> > v_overlap = ROL::makePtr<Tpetra::MultiVector<>>(this->myOverlapMap_, 1, true); 249 Tpetra::Import<> importer2(v->getMap(), v_overlap->getMap()); 250 v_overlap->doImport(*v, importer2, Tpetra::REPLACE); 251 //ApplyBCToVec (v_overlap); 252 Teuchos::ArrayRCP<const Real> vData = v_overlap->get1dView(); 253 254 Intrepid::FieldContainer<Real> u_local(this->numLocalDofs_); 255 Intrepid::FieldContainer<Real> v_local(this->numLocalDofs_); 256 257 Real SIMPDScale(0), sum(0), zero(0); 258 for(int i=0; i<this->numCells_; i++) { 259 SIMPDScale = this->SIMPmaterial_[i]->getSIMPFirstDerivativeScaleFactor(); 260 u_local.initialize(zero); 261 v_local.initialize(zero); 262 263 for(int j=0; j<this->numLocalDofs_; j++) { 264 u_local(j) = uData[u_overlap->getMap()->getLocalElement(this->cellDofs_(this->myCellIds_[i], j))]; 265 v_local(j) = vData[v_overlap->getMap()->getLocalElement(this->cellDofs_(this->myCellIds_[i], j))]; 266 } 267 268 sum = zero; 269 for(int j=0; j<this->numLocalDofs_; j++) { 270 if(this->check_myGlobalDof_on_boundary(this->cellDofs_(this->myCellIds_[i],j))) { 271 sum += u_local(j) * v_local(j); 272 } 273 else { 274 for(int k=0; k<this->numLocalDofs_; k++) { 275 if( !this->check_myGlobalDof_on_boundary(this->cellDofs_(this->myCellIds_[i],k)) ) { 276 sum += SIMPDScale * (*this->gradgradMats0_)(i, j, k) * v_local(j) * u_local(k); 277 } 278 } 279 } 280 } 281 //put value into myDensityDerivative_ 282 Jv -> replaceGlobalValue(this->myCellIds_[i], 0, sum); 283 } 284 } 285 ApplyAdjointHessian22ToVec(ROL::Ptr<Tpetra::MultiVector<>> & Hvw,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & v,const ROL::Ptr<const Tpetra::MultiVector<>> & w)286 void ApplyAdjointHessian22ToVec(ROL::Ptr<Tpetra::MultiVector<> > &Hvw, 287 const ROL::Ptr<const Tpetra::MultiVector<> > &u, 288 const ROL::Ptr<const Tpetra::MultiVector<> > &v, 289 const ROL::Ptr<const Tpetra::MultiVector<> > &w) { 290 // Hvw is myCellMap_ 291 // u should be myUniqueMap_ 292 // v should be myCellMap_ 293 // w shluld be myUniqueMapi_ 294 // 295 #ifdef ROL_TIMERS 296 Teuchos::TimeMonitor LocalTimer(*ConstraintDerivativeTime_example_PDEOPT_TOOLS_PDEFEM_GLOB); 297 #endif 298 ROL::Ptr<Tpetra::MultiVector<> > u_overlap = ROL::makePtr<Tpetra::MultiVector<>>(this->myOverlapMap_, 1, true); 299 Tpetra::Import<> importer1(u->getMap(), u_overlap->getMap()); 300 u_overlap->doImport(*u, importer1, Tpetra::REPLACE); 301 //only apply BC to U 302 this->ApplyBCToVec (u_overlap); 303 Teuchos::ArrayRCP<const Real> uData = u_overlap->get1dView(); 304 305 Tpetra::Export<> exporter(v->getMap(), this->myCellMap_); 306 ROL::Ptr<Tpetra::MultiVector<> > v_local = ROL::makePtr<Tpetra::MultiVector<>>(this->myCellMap_, 1, true); 307 v_local->doExport(*v, exporter, Tpetra::REPLACE); 308 Teuchos::ArrayRCP<const Real> vData = v_local->get1dView(); 309 310 ROL::Ptr<Tpetra::MultiVector<> > w_overlap = ROL::makePtr<Tpetra::MultiVector<>>(this->myOverlapMap_, 1, true); 311 Tpetra::Import<> importer2(w->getMap(), w_overlap->getMap()); 312 w_overlap->doImport(*w, importer2, Tpetra::REPLACE); 313 //ApplyBCToVec (w_overlap); 314 Teuchos::ArrayRCP<const Real> wData = w_overlap->get1dView(); 315 316 Intrepid::FieldContainer<Real> u_local(this->numLocalDofs_); 317 Intrepid::FieldContainer<Real> w_local(this->numLocalDofs_); 318 319 Real SIMPDDScale(0), localV(0), sum(0), zero(0); 320 321 for(int i=0; i<this->numCells_; i++) { 322 SIMPDDScale = this->SIMPmaterial_[i]->getSIMPSecondDerivativeScaleFactor(); 323 localV = vData[v_local->getMap()->getLocalElement(this->myCellIds_[i])]; 324 325 u_local.initialize(zero); 326 w_local.initialize(zero); 327 328 for(int j=0; j<this->numLocalDofs_; j++) { 329 u_local(j) = uData[u_overlap->getMap()->getLocalElement(this->cellDofs_(this->myCellIds_[i], j))]; 330 w_local(j) = wData[w_overlap->getMap()->getLocalElement(this->cellDofs_(this->myCellIds_[i], j))]; 331 } 332 333 sum = zero; 334 for(int j=0; j<this->numLocalDofs_; j++) { 335 if(this->check_myGlobalDof_on_boundary(this->cellDofs_(this->myCellIds_[i],j))) { 336 sum += u_local(j) * w_local(j); 337 } 338 else { 339 for(int k=0; k<this->numLocalDofs_; k++) { 340 if( !this->check_myGlobalDof_on_boundary(this->cellDofs_(this->myCellIds_[i],k)) ) { 341 sum += localV * SIMPDDScale * (*this->gradgradMats0_)(i, j, k) * w_local(j) * u_local(k); 342 } 343 } 344 } 345 } 346 //put value into myDensityDerivative_ 347 Hvw -> replaceGlobalValue(this->myCellIds_[i], 0, sum); 348 } 349 } 350 351 }; // class ElasticitySIMPOperators 352 353 #endif 354