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 materials.hpp 45 */ 46 47 #ifndef MATERIALS_HPP 48 #define MATERIALS_HPP 49 50 #include "Intrepid_FieldContainer.hpp" 51 52 /** \class Materials 53 */ 54 55 template <class Real> 56 class Material { 57 private: 58 59 int dim_; 60 int tensorMatSize_; 61 62 bool planeStrain_; 63 Real modulus_; 64 Real poissonRatio_; 65 ROL::Ptr<Intrepid::FieldContainer<Real> > materialTensor_; 66 67 public: 68 Material()69 Material() {} ~Material()70 virtual ~Material() {} 71 InitializeMaterial(const int dim,const bool planeStrain,const Real modulus,const Real poissonRatio)72 virtual void InitializeMaterial(const int dim, const bool planeStrain, 73 const Real modulus, const Real poissonRatio) { 74 TEUCHOS_TEST_FOR_EXCEPTION(dim > 3 || dim < 1, std::invalid_argument, 75 ">>> ERROR (InitializeMaterial): dim less than one or greater than three!"); 76 dim_ = dim; 77 planeStrain_ = planeStrain; 78 modulus_ = modulus; 79 poissonRatio_ = poissonRatio; 80 if(dim_==1) { 81 tensorMatSize_ = 1; 82 } 83 else if(dim_==2) { 84 tensorMatSize_ = 3; 85 } 86 else { 87 tensorMatSize_ = 6; 88 } 89 90 ComputeMaterialTensor(); 91 } 92 ComputeMaterialTensor(void)93 void ComputeMaterialTensor(void) { 94 materialTensor_ = ROL::makePtr<Intrepid::FieldContainer<Real>>(tensorMatSize_, tensorMatSize_); 95 materialTensor_ -> initialize(0.0); 96 if(dim_==1) { 97 (*materialTensor_)(0, 0)=modulus_; 98 } 99 else if(dim_==2 && !planeStrain_) { 100 Real one(1), half(0.5); 101 Real factor1 = modulus_ /(one-poissonRatio_*poissonRatio_); 102 (*materialTensor_)(0, 0) = factor1; 103 (*materialTensor_)(0, 1) = factor1 * poissonRatio_; 104 (*materialTensor_)(1, 0) = factor1 * poissonRatio_; 105 (*materialTensor_)(1, 1) = factor1; 106 (*materialTensor_)(2, 2) = factor1 * half * (one-poissonRatio_); 107 } 108 else if(dim_==2 && planeStrain_) { 109 Real one(1), two(2), half(0.5); 110 Real factor2 = modulus_ /(one+poissonRatio_)/(one-two*poissonRatio_); 111 (*materialTensor_)(0, 0) = factor2 * (one-poissonRatio_); 112 (*materialTensor_)(0, 1) = factor2 * poissonRatio_; 113 (*materialTensor_)(1, 0) = factor2 * poissonRatio_; 114 (*materialTensor_)(1, 1) = factor2 * (one-poissonRatio_); 115 (*materialTensor_)(2, 2) = factor2 * half * (one-two*poissonRatio_); 116 } 117 else { 118 Real one(1), two(2), half(0.5); 119 Real lam = modulus_*poissonRatio_/(one+poissonRatio_)/(one-two*poissonRatio_); 120 Real mu = half*modulus_/(one+poissonRatio_); 121 (*materialTensor_)(0, 0) = lam + two*mu; 122 (*materialTensor_)(0, 1) = lam; 123 (*materialTensor_)(0, 2) = lam; 124 (*materialTensor_)(1, 0) = lam; 125 (*materialTensor_)(1, 1) = lam + two*mu; 126 (*materialTensor_)(1, 2) = lam; 127 (*materialTensor_)(2, 0) = lam; 128 (*materialTensor_)(2, 1) = lam; 129 (*materialTensor_)(2, 2) = lam + two*mu; 130 (*materialTensor_)(3, 3) = mu; 131 (*materialTensor_)(4, 4) = mu; 132 (*materialTensor_)(5, 5) = mu; 133 } 134 } 135 GetMaterialTensor(void) const136 const ROL::Ptr<Intrepid::FieldContainer<Real> > GetMaterialTensor(void) const { 137 return materialTensor_; 138 } 139 GetMaterialTensorDim(void) const140 int GetMaterialTensorDim(void) const { 141 return tensorMatSize_; 142 } 143 GetYoungsModulus(void) const144 Real GetYoungsModulus(void) const { 145 return modulus_; 146 } 147 GetPoissonRatio(void) const148 Real GetPoissonRatio(void) const { 149 return poissonRatio_; 150 } 151 GetBulkModulus(void) const152 Real GetBulkModulus(void) const { } 153 GetShearModulus(void) const154 Real GetShearModulus(void) const { 155 Real half(0.5), one(1); 156 return half*modulus_/(one+poissonRatio_); 157 } 158 CheckMaterialTensor(void)159 void CheckMaterialTensor(void) { 160 std::cout<< *materialTensor_ <<std::endl; 161 } 162 163 }; 164 165 166 // new class for topology optimization 167 template<class Real> 168 class Material_SIMP : public Material <Real> { 169 private: 170 171 Real density_; 172 int powerP_; 173 Real minDensity_; 174 175 public: 176 InitializeSIMP(const int dim,const bool planeStrain,const Real modulus,const Real poissonRatio,const Real density,const int powerP,const Real minDensity)177 virtual void InitializeSIMP(const int dim, const bool planeStrain, 178 const Real modulus, const Real poissonRatio, 179 const Real density, const int powerP, const Real minDensity) { 180 TEUCHOS_TEST_FOR_EXCEPTION(powerP < 1, std::invalid_argument, 181 ">>> ERROR (InitializeSIMP): SIMP power is less than one!"); 182 Material<Real>::InitializeMaterial(dim, planeStrain, modulus, poissonRatio); 183 density_ = density; 184 powerP_ = powerP; 185 minDensity_ = minDensity; 186 } 187 getSIMPScaleFactor(void) const188 Real getSIMPScaleFactor(void) const { 189 TEUCHOS_TEST_FOR_EXCEPTION(powerP_ < 1, std::invalid_argument, 190 ">>> ERROR (getSIMPScaleFactor): SIMP power is less than one!"); 191 Real one(1); 192 return minDensity_ + (one-minDensity_)*std::pow(density_, powerP_); 193 } 194 getSIMPFirstDerivativeScaleFactor(void) const195 Real getSIMPFirstDerivativeScaleFactor(void) const { 196 TEUCHOS_TEST_FOR_EXCEPTION(powerP_ < 1, std::invalid_argument, 197 ">>> ERROR (getSIMPFirstDerivativeScaleFactor): SIMP power is less than one!"); 198 Real one(1); 199 return (one-minDensity_) * powerP_ * (std::pow(density_, powerP_-1)); 200 } 201 getSIMPSecondDerivativeScaleFactor(void) const202 Real getSIMPSecondDerivativeScaleFactor(void) const { 203 TEUCHOS_TEST_FOR_EXCEPTION(powerP_ < 1, std::invalid_argument, 204 ">>> ERROR (getSIMPSecondDerivativeScaleFactor): SIMP power is less than one!"); 205 Real one(1), scale(0); 206 if ( powerP_ > 1 ) { 207 scale = (one-minDensity_) * powerP_ * (powerP_-1) * (std::pow(density_, powerP_-2)); 208 } 209 return scale; 210 } 211 setDensity(const Real dens)212 void setDensity(const Real dens) { 213 density_ = dens; 214 } 215 216 // the following function is not in use computeScaledMaterialTensor(const Real scale) const217 ROL::Ptr<Intrepid::FieldContainer<Real> > computeScaledMaterialTensor(const Real scale) const { 218 Real zero(0); 219 int TMS = Material<Real>::getMaterialTensorDim(); 220 ROL::Ptr<Intrepid::FieldContainer<Real> > scaledMaterialTensor 221 = ROL::makePtr<Intrepid::FieldContainer<Real>>(TMS, TMS); 222 scaledMaterialTensor -> initialize(zero); 223 224 for(int i=0; i<TMS; i++) { 225 for(int j=0; j<TMS; j++) { 226 (*scaledMaterialTensor)(i, j) = scale * (*Material<Real>::getMaterialTensor())(i, j); 227 } 228 } 229 return scaledMaterialTensor; 230 } 231 232 }; 233 234 235 236 #endif 237 238