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 /*! \file pde.hpp 45 \brief Implements the local PDE interface for the Poisson control problem. 46 */ 47 48 #ifndef PDE_ADV_DIFF_SUR_HPP 49 #define PDE_ADV_DIFF_SUR_HPP 50 51 #include "../../TOOLS/pde.hpp" 52 #include "../../TOOLS/fe.hpp" 53 54 #include "Intrepid_HGRAD_QUAD_C1_FEM.hpp" 55 #include "Intrepid_HGRAD_QUAD_C2_FEM.hpp" 56 #include "Intrepid_HGRAD_HEX_C1_FEM.hpp" 57 #include "Intrepid_HGRAD_HEX_C2_FEM.hpp" 58 #include "Intrepid_DefaultCubatureFactory.hpp" 59 #include "Intrepid_FunctionSpaceTools.hpp" 60 #include "Intrepid_CellTools.hpp" 61 62 #include "ROL_Ptr.hpp" 63 64 template <class Real> 65 class PDE_adv_diff : public PDE<Real> { 66 private: 67 // Finite element basis information 68 ROL::Ptr<Intrepid::Basis<Real, Intrepid::FieldContainer<Real>>> basisPtr_; 69 std::vector<ROL::Ptr<Intrepid::Basis<Real, Intrepid::FieldContainer<Real>>>> basisPtrs_; 70 ROL::Ptr<Intrepid::Basis<Real, Intrepid::FieldContainer<Real>>> basisPtr2_; 71 std::vector<ROL::Ptr<Intrepid::Basis<Real, Intrepid::FieldContainer<Real>>>> basisPtrs2_; 72 // Cell cubature information 73 ROL::Ptr<Intrepid::Cubature<Real>> cellCub_; 74 // Cell node information 75 ROL::Ptr<Intrepid::FieldContainer<Real>> volCellNodes_; 76 std::vector<std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>>> bdryCellNodes_; 77 std::vector<std::vector<std::vector<int>>> bdryCellLocIds_; 78 // Finite element definition 79 ROL::Ptr<FE<Real>> fe_vol_, fe_ctrl_; 80 // Local degrees of freedom on boundary, for each side of the reference cell (first index). 81 std::vector<std::vector<int>> fidx_; 82 // Coordinates of degrees freedom on boundary cells. 83 // Indexing: [sideset number][local side id](cell number, value at dof) 84 std::vector<std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>>> bdryCellDofValues_; 85 86 int nx_, ny_; 87 Real XL_, XU_, YL_, YU_; 88 bool usePC_; 89 90 public: PDE_adv_diff(Teuchos::ParameterList & parlist)91 PDE_adv_diff(Teuchos::ParameterList &parlist) { 92 // Finite element fields. 93 int basisOrder = parlist.sublist("Problem").get("Order of FE Discretization",1); 94 int cubDegree = parlist.sublist("Problem").get("Cubature Degree",4); 95 int probDim = parlist.sublist("Problem").get("Problem Dimension",2); 96 if (probDim == 2) { 97 if (basisOrder == 1) { 98 basisPtr_ = ROL::makePtr<Intrepid::Basis_HGRAD_QUAD_C1_FEM<Real, Intrepid::FieldContainer<Real>>>(); 99 } 100 else if (basisOrder == 2) { 101 basisPtr_ = ROL::makePtr<Intrepid::Basis_HGRAD_QUAD_C2_FEM<Real, Intrepid::FieldContainer<Real>>>(); 102 } 103 } 104 else if (probDim == 3) { 105 if (basisOrder == 1) { 106 basisPtr_ = ROL::makePtr<Intrepid::Basis_HGRAD_HEX_C1_FEM<Real, Intrepid::FieldContainer<Real>>>(); 107 } 108 else if (basisOrder == 2) { 109 basisPtr_ = ROL::makePtr<Intrepid::Basis_HGRAD_HEX_C2_FEM<Real, Intrepid::FieldContainer<Real>>>(); 110 } 111 } 112 basisPtrs_.clear(); basisPtrs_.push_back(basisPtr_); 113 // Quadrature rules. 114 shards::CellTopology cellType = basisPtr_->getBaseCellTopology(); // get the cell type from any basis 115 Intrepid::DefaultCubatureFactory<Real> cubFactory; // create cubature factory 116 cellCub_ = cubFactory.create(cellType, cubDegree); // create default cubature 117 118 nx_ = parlist.sublist("Problem").get("Number of X-Cells", 4); 119 ny_ = parlist.sublist("Problem").get("Number of Y-Cells", 2); 120 XL_ = parlist.sublist("Geometry").get("X0", 0.0); 121 YL_ = parlist.sublist("Geometry").get("Y0", 0.0); 122 XU_ = XL_ + parlist.sublist("Geometry").get("Width", 2.0); 123 YU_ = YL_ + parlist.sublist("Geometry").get("Height", 1.0); 124 usePC_ = parlist.sublist("Problem").get("Piecewise Constant Controls", true); 125 if (!usePC_) { 126 if (probDim == 2) { 127 basisPtr2_ = ROL::makePtr<Intrepid::Basis_HGRAD_QUAD_C1_FEM<Real, Intrepid::FieldContainer<Real>>>(); 128 } 129 else if (probDim == 3) { 130 basisPtr2_ = ROL::makePtr<Intrepid::Basis_HGRAD_HEX_C1_FEM<Real, Intrepid::FieldContainer<Real>>>(); 131 } 132 basisPtrs2_.clear(); basisPtrs2_.push_back(basisPtr2_); 133 } 134 } 135 residual(ROL::Ptr<Intrepid::FieldContainer<Real>> & res,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff=ROL::nullPtr,const ROL::Ptr<const std::vector<Real>> & z_param=ROL::nullPtr)136 void residual(ROL::Ptr<Intrepid::FieldContainer<Real>> & res, 137 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff, 138 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff = ROL::nullPtr, 139 const ROL::Ptr<const std::vector<Real>> & z_param = ROL::nullPtr) { 140 // GET DIMENSIONS 141 int c = fe_vol_->gradN()->dimension(0); 142 int f = fe_vol_->gradN()->dimension(1); 143 int p = fe_vol_->gradN()->dimension(2); 144 int d = fe_vol_->gradN()->dimension(3); 145 // INITIALIZE RESIDUAL AND STORAGE 146 res = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, f); 147 ROL::Ptr<Intrepid::FieldContainer<Real>> kappa, V; 148 ROL::Ptr<Intrepid::FieldContainer<Real>> gradU_eval, kappa_gradU, V_gradU, valZ_eval; 149 kappa = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, p); 150 V = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, p, d); 151 gradU_eval = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, p, d); 152 kappa_gradU = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, p, d); 153 V_gradU = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, p); 154 valZ_eval = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, p); 155 // COMPUTE PDE COEFFICIENTS 156 computeCoefficients(kappa,V); 157 // EVALUE GRADIENT OF U AT QUADRATURE POINTS 158 fe_vol_->evaluateGradient(gradU_eval, u_coeff); 159 // COMPUTE DIFFUSION TERM 160 Intrepid::FunctionSpaceTools::tensorMultiplyDataData<Real>(*kappa_gradU, 161 *kappa, 162 *gradU_eval); 163 Intrepid::FunctionSpaceTools::integrate<Real>(*res, 164 *kappa_gradU, 165 *fe_vol_->gradNdetJ(), 166 Intrepid::COMP_CPP, false); 167 // ADD ADVECTION TERM TO RESIDUAL 168 Intrepid::FunctionSpaceTools::dotMultiplyDataData<Real>(*V_gradU, 169 *V, 170 *gradU_eval); 171 Intrepid::FunctionSpaceTools::integrate<Real>(*res, 172 *V_gradU, 173 *fe_vol_->NdetJ(), 174 Intrepid::COMP_CPP, true); 175 176 // ADD CONTROL TERM TO RESIDUAL 177 if (z_coeff != ROL::nullPtr) { 178 fe_ctrl_->evaluateValue(valZ_eval, z_coeff); 179 Intrepid::RealSpaceTools<Real>::scale(*valZ_eval,static_cast<Real>(-1)); 180 Intrepid::FunctionSpaceTools::integrate<Real>(*res, 181 *valZ_eval, 182 *fe_vol_->NdetJ(), 183 Intrepid::COMP_CPP, true); 184 } 185 else { 186 addControlOperator(valZ_eval,z_param); 187 Intrepid::FunctionSpaceTools::integrate<Real>(*res, 188 *valZ_eval, 189 *fe_vol_->NdetJ(), 190 Intrepid::COMP_CPP, true); 191 } 192 // APPLY DIRICHLET CONDITIONS 193 int numLocalSideIds = bdryCellLocIds_[0].size(); 194 for (int j = 0; j < numLocalSideIds; ++j) { 195 int numCellsSide = bdryCellLocIds_[0][j].size(); 196 int numBdryDofs = fidx_[j].size(); 197 for (int k = 0; k < numCellsSide; ++k) { 198 int cidx = bdryCellLocIds_[0][j][k]; 199 for (int l = 0; l < numBdryDofs; ++l) { 200 (*res)(cidx,fidx_[j][l]) 201 = (*u_coeff)(cidx,fidx_[j][l]) - (*bdryCellDofValues_[0][j])(k,fidx_[j][l]); 202 } 203 } 204 } 205 } 206 Jacobian_1(ROL::Ptr<Intrepid::FieldContainer<Real>> & jac,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff=ROL::nullPtr,const ROL::Ptr<const std::vector<Real>> & z_param=ROL::nullPtr)207 void Jacobian_1(ROL::Ptr<Intrepid::FieldContainer<Real>> & jac, 208 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff, 209 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff = ROL::nullPtr, 210 const ROL::Ptr<const std::vector<Real>> & z_param = ROL::nullPtr) { 211 // GET DIMENSIONS 212 int c = fe_vol_->gradN()->dimension(0); 213 int f = fe_vol_->gradN()->dimension(1); 214 int p = fe_vol_->gradN()->dimension(2); 215 int d = fe_vol_->gradN()->dimension(3); 216 // INITILAIZE JACOBIAN AND STORAGE 217 jac = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, f, f); 218 ROL::Ptr<Intrepid::FieldContainer<Real>> kappa, V, kappa_gradN, V_gradN; 219 kappa = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, p); 220 V = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, p, d); 221 kappa_gradN = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, f, p, d); 222 V_gradN = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, f, p); 223 // COMPUTE PDE COEFFICIENTS 224 computeCoefficients(kappa,V); 225 // COMPUTE DIFFUSION TERM 226 Intrepid::FunctionSpaceTools::tensorMultiplyDataField<Real>(*kappa_gradN, 227 *kappa, 228 *fe_vol_->gradN()); 229 Intrepid::FunctionSpaceTools::integrate<Real>(*jac, 230 *kappa_gradN, 231 *fe_vol_->gradNdetJ(), 232 Intrepid::COMP_CPP, false); 233 // ADD ADVECTION TERM TO JACOBIAN 234 Intrepid::FunctionSpaceTools::dotMultiplyDataField<Real>(*V_gradN, 235 *V, 236 *fe_vol_->gradN()); 237 Intrepid::FunctionSpaceTools::integrate<Real>(*jac, 238 *fe_vol_->NdetJ(), 239 *V_gradN, 240 Intrepid::COMP_CPP, true); 241 // APPLY DIRICHLET CONDITIONS 242 int numLocalSideIds = bdryCellLocIds_[0].size(); 243 for (int j = 0; j < numLocalSideIds; ++j) { 244 int numCellsSide = bdryCellLocIds_[0][j].size(); 245 int numBdryDofs = fidx_[j].size(); 246 for (int k = 0; k < numCellsSide; ++k) { 247 int cidx = bdryCellLocIds_[0][j][k]; 248 for (int l = 0; l < numBdryDofs; ++l) { 249 //std::cout << "\n j=" << j << " l=" << l << " " << fidx[j][l]; 250 for (int m = 0; m < f; ++m) { 251 (*jac)(cidx,fidx_[j][l],m) = static_cast<Real>(0); 252 } 253 (*jac)(cidx,fidx_[j][l],fidx_[j][l]) = static_cast<Real>(1); 254 } 255 } 256 } 257 } 258 Jacobian_2(ROL::Ptr<Intrepid::FieldContainer<Real>> & jac,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff=ROL::nullPtr,const ROL::Ptr<const std::vector<Real>> & z_param=ROL::nullPtr)259 void Jacobian_2(ROL::Ptr<Intrepid::FieldContainer<Real>> & jac, 260 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff, 261 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff = ROL::nullPtr, 262 const ROL::Ptr<const std::vector<Real>> & z_param = ROL::nullPtr) { 263 if (z_coeff != ROL::nullPtr) { 264 // GET DIMENSIONS 265 int c = fe_vol_->N()->dimension(0); 266 int f1 = fe_vol_->N()->dimension(1); 267 int f2 = fe_ctrl_->N()->dimension(1); 268 // INITIALIZE RIESZ 269 jac = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, f1, f2); 270 Intrepid::FunctionSpaceTools::integrate<Real>(*jac, 271 *fe_vol_->N(), 272 *fe_ctrl_->NdetJ(), 273 Intrepid::COMP_CPP, false); 274 //*jac = *fe_vol_->massMat(); 275 Intrepid::RealSpaceTools<Real>::scale(*jac,static_cast<Real>(-1)); 276 // APPLY DIRICHLET CONDITIONS 277 int numLocalSideIds = bdryCellLocIds_[0].size(); 278 for (int j = 0; j < numLocalSideIds; ++j) { 279 int numCellsSide = bdryCellLocIds_[0][j].size(); 280 int numBdryDofs = fidx_[j].size(); 281 for (int k = 0; k < numCellsSide; ++k) { 282 int cidx = bdryCellLocIds_[0][j][k]; 283 for (int l = 0; l < numBdryDofs; ++l) { 284 //std::cout << "\n j=" << j << " l=" << l << " " << fidx[j][l]; 285 for (int m = 0; m < f2; ++m) { 286 (*jac)(cidx,fidx_[j][l],m) = static_cast<Real>(0); 287 } 288 } 289 } 290 } 291 } 292 else { 293 throw Exception::Zero(">>> (PDE_stoch_adv_diff::Jacobian_2): Jacobian is zero."); 294 } 295 } 296 Jacobian_3(std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> & jac,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff=ROL::nullPtr,const ROL::Ptr<const std::vector<Real>> & z_param=ROL::nullPtr)297 void Jacobian_3(std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> & jac, 298 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff, 299 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff = ROL::nullPtr, 300 const ROL::Ptr<const std::vector<Real>> & z_param = ROL::nullPtr) { 301 if (z_coeff != ROL::nullPtr) { 302 throw Exception::Zero(">>> (PDE_stoch_adv_diff::Jacobian_3): Jacobian is zero."); 303 } 304 else { 305 // GET DIMENSIONS 306 int c = fe_vol_->gradN()->dimension(0); 307 int f = fe_vol_->gradN()->dimension(1); 308 int p = fe_vol_->gradN()->dimension(2); 309 // ADD CONTROL TERM TO RESIDUAL 310 ROL::Ptr<Intrepid::FieldContainer<Real>> ctrl 311 = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, p); 312 ROL::Ptr<Intrepid::FieldContainer<Real>> B 313 = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, p); 314 for (int i = 0; i < nx_; ++i) { 315 for (int j = 0; j < ny_; ++j) { 316 int ind = i + j*nx_; 317 jac[ind] = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, f); 318 addControlJaobian(B,i,j); 319 Intrepid::FunctionSpaceTools::integrate<Real>(*jac[ind], 320 *B, 321 *fe_vol_->NdetJ(), 322 Intrepid::COMP_CPP, false); 323 // APPLY DIRICHLET CONDITIONS 324 int numLocalSideIds = bdryCellLocIds_[0].size(); 325 for (int k = 0; k < numLocalSideIds; ++k) { 326 int numCellsSide = bdryCellLocIds_[0][k].size(); 327 int numBdryDofs = fidx_[k].size(); 328 for (int l = 0; l < numCellsSide; ++l) { 329 int cidx = bdryCellLocIds_[0][k][l]; 330 for (int m = 0; m < numBdryDofs; ++m) { 331 (*(jac[ind]))(cidx,fidx_[k][m]) = static_cast<Real>(0); 332 } 333 } 334 } 335 } 336 } 337 } 338 } 339 Hessian_11(ROL::Ptr<Intrepid::FieldContainer<Real>> & hess,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & l_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff=ROL::nullPtr,const ROL::Ptr<const std::vector<Real>> & z_param=ROL::nullPtr)340 void Hessian_11(ROL::Ptr<Intrepid::FieldContainer<Real>> & hess, 341 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & l_coeff, 342 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff, 343 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff = ROL::nullPtr, 344 const ROL::Ptr<const std::vector<Real>> & z_param = ROL::nullPtr) { 345 throw Exception::Zero(">>> (PDE_stoch_adv_diff::Hessian_11): Hessian is zero."); 346 } 347 Hessian_12(ROL::Ptr<Intrepid::FieldContainer<Real>> & hess,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & l_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff=ROL::nullPtr,const ROL::Ptr<const std::vector<Real>> & z_param=ROL::nullPtr)348 void Hessian_12(ROL::Ptr<Intrepid::FieldContainer<Real>> & hess, 349 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & l_coeff, 350 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff, 351 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff = ROL::nullPtr, 352 const ROL::Ptr<const std::vector<Real>> & z_param = ROL::nullPtr) { 353 throw Exception::Zero(">>> (PDE_stoch_adv_diff::Hessian_12): Hessian is zero."); 354 } 355 Hessian_13(std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> & hess,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & l_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff=ROL::nullPtr,const ROL::Ptr<const std::vector<Real>> & z_param=ROL::nullPtr)356 void Hessian_13(std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> & hess, 357 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & l_coeff, 358 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff, 359 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff = ROL::nullPtr, 360 const ROL::Ptr<const std::vector<Real>> & z_param = ROL::nullPtr) { 361 throw Exception::Zero(">>> (PDE_stoch_adv_diff::Hessian_13): Hessian is zero."); 362 } 363 Hessian_21(ROL::Ptr<Intrepid::FieldContainer<Real>> & hess,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & l_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff=ROL::nullPtr,const ROL::Ptr<const std::vector<Real>> & z_param=ROL::nullPtr)364 void Hessian_21(ROL::Ptr<Intrepid::FieldContainer<Real>> & hess, 365 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & l_coeff, 366 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff, 367 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff = ROL::nullPtr, 368 const ROL::Ptr<const std::vector<Real>> & z_param = ROL::nullPtr) { 369 throw Exception::Zero(">>> (PDE_stoch_adv_diff::Hessian_21): Hessian is zero."); 370 } 371 Hessian_22(ROL::Ptr<Intrepid::FieldContainer<Real>> & hess,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & l_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff=ROL::nullPtr,const ROL::Ptr<const std::vector<Real>> & z_param=ROL::nullPtr)372 void Hessian_22(ROL::Ptr<Intrepid::FieldContainer<Real>> & hess, 373 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & l_coeff, 374 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff, 375 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff = ROL::nullPtr, 376 const ROL::Ptr<const std::vector<Real>> & z_param = ROL::nullPtr) { 377 throw Exception::Zero(">>> (PDE_stoch_adv_diff::Hessian_22): Hessian is zero."); 378 } 379 Hessian_23(std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> & hess,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & l_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff=ROL::nullPtr,const ROL::Ptr<const std::vector<Real>> & z_param=ROL::nullPtr)380 void Hessian_23(std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> & hess, 381 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & l_coeff, 382 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff, 383 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff = ROL::nullPtr, 384 const ROL::Ptr<const std::vector<Real>> & z_param = ROL::nullPtr) { 385 throw Exception::Zero(">>> (PDE_stoch_adv_diff::Hessian_23): Hessian is zero."); 386 } 387 Hessian_31(std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> & hess,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & l_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff=ROL::nullPtr,const ROL::Ptr<const std::vector<Real>> & z_param=ROL::nullPtr)388 void Hessian_31(std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> & hess, 389 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & l_coeff, 390 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff, 391 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff = ROL::nullPtr, 392 const ROL::Ptr<const std::vector<Real>> & z_param = ROL::nullPtr) { 393 throw Exception::Zero(">>> (PDE_stoch_adv_diff::Hessian_31): Hessian is zero."); 394 } 395 Hessian_32(std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> & hess,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & l_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff=ROL::nullPtr,const ROL::Ptr<const std::vector<Real>> & z_param=ROL::nullPtr)396 void Hessian_32(std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> & hess, 397 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & l_coeff, 398 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff, 399 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff = ROL::nullPtr, 400 const ROL::Ptr<const std::vector<Real>> & z_param = ROL::nullPtr) { 401 throw Exception::Zero(">>> (PDE_stoch_adv_diff::Hessian_32): Hessian is zero."); 402 } 403 Hessian_33(std::vector<std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>>> & hess,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & l_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff,const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff=ROL::nullPtr,const ROL::Ptr<const std::vector<Real>> & z_param=ROL::nullPtr)404 void Hessian_33(std::vector<std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>>> & hess, 405 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & l_coeff, 406 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & u_coeff, 407 const ROL::Ptr<const Intrepid::FieldContainer<Real>> & z_coeff = ROL::nullPtr, 408 const ROL::Ptr<const std::vector<Real>> & z_param = ROL::nullPtr) { 409 throw Exception::Zero(">>> (PDE_stoch_adv_diff::Hessian_33): Hessian is zero."); 410 } 411 RieszMap_1(ROL::Ptr<Intrepid::FieldContainer<Real>> & riesz)412 void RieszMap_1(ROL::Ptr<Intrepid::FieldContainer<Real>> & riesz) { 413 // GET DIMENSIONS 414 int c = fe_vol_->N()->dimension(0); 415 int f = fe_vol_->N()->dimension(1); 416 // INITIALIZE RIESZ 417 riesz = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, f, f); 418 *riesz = *fe_vol_->stiffMat(); 419 Intrepid::RealSpaceTools<Real>::add(*riesz,*(fe_vol_->massMat())); 420 } 421 RieszMap_2(ROL::Ptr<Intrepid::FieldContainer<Real>> & riesz)422 void RieszMap_2(ROL::Ptr<Intrepid::FieldContainer<Real>> & riesz) { 423 // GET DIMENSIONS 424 int c = fe_ctrl_->N()->dimension(0); 425 int f = fe_ctrl_->N()->dimension(1); 426 // INITIALIZE RIESZ 427 riesz = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, f, f); 428 *riesz = *fe_ctrl_->massMat(); 429 } 430 getFields()431 std::vector<ROL::Ptr<Intrepid::Basis<Real, Intrepid::FieldContainer<Real>>>> getFields() { 432 return basisPtrs_; 433 } 434 getFields2()435 std::vector<ROL::Ptr<Intrepid::Basis<Real, Intrepid::FieldContainer<Real>>>> getFields2() { 436 return basisPtrs2_; 437 } 438 setCellNodes(const ROL::Ptr<Intrepid::FieldContainer<Real>> & volCellNodes,const std::vector<std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>>> & bdryCellNodes,const std::vector<std::vector<std::vector<int>>> & bdryCellLocIds)439 void setCellNodes(const ROL::Ptr<Intrepid::FieldContainer<Real>> &volCellNodes, 440 const std::vector<std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>>> &bdryCellNodes, 441 const std::vector<std::vector<std::vector<int>>> &bdryCellLocIds) { 442 volCellNodes_ = volCellNodes; 443 bdryCellNodes_ = bdryCellNodes; 444 bdryCellLocIds_ = bdryCellLocIds; 445 // Finite element definition. 446 fe_vol_ = ROL::makePtr<FE<Real>>(volCellNodes_,basisPtr_,cellCub_); 447 if (!usePC_) { 448 fe_ctrl_ = ROL::makePtr<FE<Real>>(volCellNodes_,basisPtr2_,cellCub_); 449 } 450 // Set local boundary DOFs. 451 fidx_ = fe_vol_->getBoundaryDofs(); 452 // Compute Dirichlet values at DOFs. 453 int d = basisPtr_->getBaseCellTopology().getDimension(); 454 int numSidesets = bdryCellLocIds_.size(); 455 bdryCellDofValues_.resize(numSidesets); 456 for (int i=0; i<numSidesets; ++i) { 457 int numLocSides = bdryCellLocIds_[i].size(); 458 bdryCellDofValues_[i].resize(numLocSides); 459 for (int j=0; j<numLocSides; ++j) { 460 int c = bdryCellLocIds_[i][j].size(); 461 int f = basisPtr_->getCardinality(); 462 bdryCellDofValues_[i][j] = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, f); 463 ROL::Ptr<Intrepid::FieldContainer<Real>> coords = 464 ROL::makePtr<Intrepid::FieldContainer<Real>>(c, f, d); 465 if (c > 0) { 466 fe_vol_->computeDofCoords(coords, bdryCellNodes_[i][j]); 467 } 468 for (int k=0; k<c; ++k) { 469 for (int l=0; l<f; ++l) { 470 std::vector<Real> dofpoint(d); 471 for (int m=0; m<d; ++m) { 472 dofpoint[m] = (*coords)(k, l, m); 473 } 474 (*bdryCellDofValues_[i][j])(k, l) = evaluateDirichlet(dofpoint, i, j); 475 } 476 } 477 } 478 } 479 } 480 getFE(void) const481 const ROL::Ptr<FE<Real>> getFE(void) const { 482 return fe_vol_; 483 } 484 getFE2(void) const485 const ROL::Ptr<FE<Real>> getFE2(void) const { 486 return fe_ctrl_; 487 } 488 print(void) const489 void print(void) const { 490 std::ofstream xfile, yfile; 491 xfile.open("X.txt"); 492 yfile.open("Y.txt"); 493 for (int i = 0; i < nx_; ++i) { 494 for (int j = 0; j < ny_; ++j) { 495 xfile << i << std::endl; 496 yfile << j << std::endl; 497 } 498 } 499 xfile.close(); 500 yfile.close(); 501 } 502 503 private: 504 evaluateDirichlet(const std::vector<Real> & coords,int sideset,int locSideId) const505 Real evaluateDirichlet(const std::vector<Real> & coords, int sideset, int locSideId) const { 506 return static_cast<Real>(0); 507 } 508 evaluateDiffusivity(const std::vector<Real> & x) const509 Real evaluateDiffusivity(const std::vector<Real> &x) const { 510 return static_cast<Real>(0.01); 511 } 512 evaluateVelocity(std::vector<Real> & adv,const std::vector<Real> & x) const513 void evaluateVelocity(std::vector<Real> &adv, const std::vector<Real> &x) const { 514 adv.assign(x.size(),static_cast<Real>(0)); 515 adv[0] = static_cast<Real>(1); 516 } 517 computeCoefficients(ROL::Ptr<Intrepid::FieldContainer<Real>> & kappa,ROL::Ptr<Intrepid::FieldContainer<Real>> & V) const518 void computeCoefficients(ROL::Ptr<Intrepid::FieldContainer<Real>> &kappa, 519 ROL::Ptr<Intrepid::FieldContainer<Real>> &V) const { 520 // GET DIMENSIONS 521 int c = fe_vol_->gradN()->dimension(0); 522 int p = fe_vol_->gradN()->dimension(2); 523 int d = fe_vol_->gradN()->dimension(3); 524 std::vector<Real> pt(d), adv(d); 525 for (int i = 0; i < c; ++i) { 526 for (int j = 0; j < p; ++j) { 527 for ( int k = 0; k < d; ++k) { 528 pt[k] = (*fe_vol_->cubPts())(i,j,k); 529 } 530 // Compute diffusivity kappa 531 (*kappa)(i,j) = evaluateDiffusivity(pt); 532 // Compute advection velocity field V 533 evaluateVelocity(adv,pt); 534 for (int k = 0; k < d; ++k) { 535 (*V)(i,j,k) = adv[k]; 536 } 537 } 538 } 539 } 540 addControlOperator(ROL::Ptr<Intrepid::FieldContainer<Real>> & Bz,const ROL::Ptr<const std::vector<Real>> & z) const541 void addControlOperator(ROL::Ptr<Intrepid::FieldContainer<Real>> &Bz, 542 const ROL::Ptr<const std::vector<Real>> &z) const { 543 // GET DIMENSIONS 544 int c = fe_vol_->gradN()->dimension(0); 545 int p = fe_vol_->gradN()->dimension(2); 546 int d = fe_vol_->gradN()->dimension(3); 547 std::vector<Real> pt(d); 548 Real xl(0), xu(0), yl(0), yu(0); 549 Bz->initialize(); 550 for (int i = 0; i < c; ++i) { 551 for (int j = 0; j < p; ++j) { 552 for ( int k = 0; k < d; ++k) { 553 pt[k] = (*fe_vol_->cubPts())(i,j,k); 554 } 555 for (int l = 0; l < nx_; ++l) { 556 xl = XL_ + static_cast<Real>(l)*(XU_-XL_)/static_cast<Real>(nx_); 557 xu = XL_ + static_cast<Real>(l+1)*(XU_-XL_)/static_cast<Real>(nx_); 558 if ( pt[0] < xu && pt[0] >= xl ) { 559 for (int m = 0; m < ny_; ++m) { 560 int ind = l + m*nx_; 561 yl = YL_ + static_cast<Real>(m)*(YU_-YL_)/static_cast<Real>(ny_); 562 yu = YL_ + static_cast<Real>(m+1)*(YU_-YL_)/static_cast<Real>(ny_); 563 if ( pt[1] < yu && pt[1] >= yl ) { 564 (*Bz)(i,j) -= (*z)[ind]; 565 } 566 } 567 } 568 } 569 } 570 } 571 } 572 addControlJaobian(ROL::Ptr<Intrepid::FieldContainer<Real>> & B,int l,int m) const573 void addControlJaobian(ROL::Ptr<Intrepid::FieldContainer<Real>> &B, 574 int l, int m) const { 575 // GET DIMENSIONS 576 int c = fe_vol_->gradN()->dimension(0); 577 int p = fe_vol_->gradN()->dimension(2); 578 int d = fe_vol_->gradN()->dimension(3); 579 std::vector<Real> pt(d); 580 Real xl(0), xu(0), yl(0), yu(0); 581 xl = XL_ + static_cast<Real>(l)*(XU_-XL_)/static_cast<Real>(nx_); 582 xu = XL_ + static_cast<Real>(l+1)*(XU_-XL_)/static_cast<Real>(nx_); 583 yl = YL_ + static_cast<Real>(m)*(YU_-YL_)/static_cast<Real>(ny_); 584 yu = YL_ + static_cast<Real>(m+1)*(YU_-YL_)/static_cast<Real>(ny_); 585 int ind = l + m*nx_; 586 B->initialize(); 587 for (int i = 0; i < c; ++i) { 588 for (int j = 0; j < p; ++j) { 589 for ( int k = 0; k < d; ++k) { 590 pt[k] = (*fe_vol_->cubPts())(i,j,k); 591 } 592 if ( pt[0] < xu && pt[0] >= xl && pt[1] < yu && pt[1] >= yl ) { 593 (*B)(i,j) = static_cast<Real>(-1); 594 } 595 } 596 } 597 } 598 599 }; // PDE_stoch_adv_diff 600 601 #endif 602