1 /*! 2 * \file src/NUMODIS/Crystallo.cxx 3 * \brief 4 * \author Laurent Dupuy 5 * \date 9/06/2017 6 * \copyright Copyright (C) 2006-2018 CEA/DEN, EDF R&D. All rights 7 * reserved. 8 * This project is publicly released under either the GNU GPL Licence 9 * or the CECILL-A licence. A copy of thoses licences are delivered 10 * with the sources of TFEL. CEA or EDF may also distribute this 11 * project under specific licensing conditions. 12 */ 13 14 #include <stdexcept> 15 #include <sstream> 16 #include <vector> 17 #include <string> 18 19 #include "TFEL/Raise.hxx" 20 #include "NUMODIS/Math/Utilities.hxx" 21 #include "NUMODIS/GSystem.hxx" 22 #include "NUMODIS/Crystallo.hxx" 23 24 namespace numodis 25 { 26 27 Crystallo::Crystallo() = default; 28 29 Crystallo::Crystallo(Crystallo&&) = default; 30 31 Crystallo::Crystallo(const Crystallo&) = default; 32 33 //=============================================================== 34 // Crystallo::InitGSystem 35 //--------------------------------------------------------------- 36 //! Construct a crystallographic verified glide system 37 //--------------------------------------------------------------- 38 /*! 39 \param iburgers a Burgers vector 40 \param iplane a glide plane 41 \return a glide system 42 */ 43 //=============================================================== InitGSystem(const IBurgers & iburgers,const IPlane & iplane) const44 GSystem Crystallo::InitGSystem(const IBurgers& iburgers, 45 const IPlane& iplane) const 46 { 47 if (this->ScalProduct(iplane,iburgers)!=0){ 48 std::ostringstream os; 49 os << "Crystallo::InitGSystem: ill-defined glide system" 50 << "'" << iburgers << iplane << "'"; 51 tfel::raise(os.str()); 52 } 53 return GSystem(iburgers,iplane); 54 } 55 direction(const IDirection & idirection) const56 Vect3 Crystallo::direction(const IDirection& idirection) const 57 { 58 // rotation 59 Vect3 xdirection; 60 for(unsigned i=0; i<_alattice.size(); i++){ 61 xdirection+=static_cast<double>(idirection.getIndex()[i])*_alattice[i]; 62 } 63 // convert to a unit vector 64 xdirection.Normalize(); 65 return xdirection; 66 } 67 68 normal(const IPlane & iplane) const69 Vect3 Crystallo::normal(const IPlane& iplane) const 70 { 71 // rotation 72 Vect3 xdirection; 73 for(unsigned i=0; i<this->_alattice.size(); i++) 74 xdirection+=static_cast<double>(iplane[i])*(this->_plattice[i]); 75 // convert to a unit vector 76 xdirection.Normalize(); 77 return xdirection; 78 } 79 burgers_vector(const IBurgers & iburgers) const80 Vect3 Crystallo::burgers_vector(const IBurgers& iburgers) const 81 { 82 Vect3 xburgers; 83 for(unsigned i=0; i<_blattice.size(); i++){ 84 xburgers+=static_cast<double>(iburgers.getIndex()[i])*_blattice[i]; 85 } 86 return xburgers; 87 } 88 89 //===================================================================== 90 // Crystallo::ComputeJunctionGSystem 91 //--------------------------------------------------------------------- 92 //! Compute the glide system of a junction between two glide systems 93 //--------------------------------------------------------------------- 94 /*! 95 \param gsystem1 first glide system 96 \param gsystem2 second glide system 97 \return output glide system 98 */ 99 //===================================================================== ComputeJunctionGSystem(const GSystem & gsystem1,const GSystem & gsystem2) const100 GSystem Crystallo::ComputeJunctionGSystem(const GSystem& gsystem1, 101 const GSystem& gsystem2) const 102 { 103 104 // same glide plane? 105 if(gsystem1.getIPlane()==gsystem2.getIPlane()) 106 { 107 108 if(Coincide(gsystem1.getIBurgers(),gsystem2.getIBurgers())!=0) 109 { 110 111 // self junction 112 throw -1; 113 } 114 else 115 { 116 // add Burgers vectors 117 IBurgers iburgers3a(gsystem1.getIBurgers()+gsystem2.getIBurgers()); 118 IBurgers iburgers3b(gsystem1.getIBurgers()-gsystem2.getIBurgers()); 119 120 // consider the smallest one 121 IBurgers ijunctionBurgers( this->Norm2(iburgers3a)<this->Norm2(iburgers3b) ? iburgers3a : iburgers3b ); 122 123 // return new glide system 124 return this->InitGSystem(ijunctionBurgers,gsystem1.getIPlane()); 125 } 126 } 127 else { 128 if(Coincide(gsystem1.getIBurgers(),gsystem2.getIBurgers())!=0){ 129 // colinear situation 130 throw -2; 131 } 132 // compute junction direction 133 IDirection ijunction(this->getNindices());; 134 this->CrossProduct(gsystem1.getIPlane(),gsystem2.getIPlane(),ijunction); 135 136 // add Burgers vectors 137 IBurgers iburgers3a(gsystem1.getIBurgers()+gsystem2.getIBurgers()); 138 IBurgers iburgers3b(gsystem1.getIBurgers()-gsystem2.getIBurgers()); 139 140 // consider the smallest 141 Vect3 xjunction = this->direction(ijunction); 142 Vect3 xburgers3a = this->burgers_vector(iburgers3a); 143 Vect3 xburgers3b = this->burgers_vector(iburgers3b); 144 double E3a = xburgers3a.SquareLength()*(1-0.3*pow(xjunction.Dot(xburgers3a.UnitVector()),2)); 145 double E3b = xburgers3b.SquareLength()*(1-0.3*pow(xjunction.Dot(xburgers3b.UnitVector()),2)); 146 147 IBurgers ijunctionBurgers( E3a<E3b ? iburgers3a : iburgers3b ); 148 149 // compute the glide plane 150 IPlane ijunctionPlane(this->getNindices()); 151 this->CrossProduct(ijunctionBurgers,ijunction,ijunctionPlane); 152 153 // return new glide system 154 return this->InitGSystem(ijunctionBurgers,ijunctionPlane); 155 } 156 } 157 158 //===================================================================== 159 // Crystallo::GenerateEquivalentGSystems 160 //--------------------------------------------------------------------- 161 //! Provide a vector of all equivalent glide systems 162 //--------------------------------------------------------------------- 163 /*! 164 \param gsystem reference glide system 165 \param allGSystems all equivalet glide systems 166 */ 167 //===================================================================== GenerateEquivalentGSystems(const GSystem & gsystem,std::vector<GSystem> & allGSystems) const168 void Crystallo::GenerateEquivalentGSystems(const GSystem& gsystem, 169 std::vector<GSystem>& allGSystems) const 170 { 171 172 // generate all planes 173 std::vector<IPlane> allPlanes; 174 this->GenerateEquivalentPlanes(gsystem.getIPlane(),allPlanes); 175 176 // generate all the other Burgers vector 177 std::vector<IBurgers> allBurgers; 178 this->GenerateEquivalentIBurgers(gsystem.getIBurgers(),allBurgers); 179 180 // generate all glide systems 181 for(decltype(allPlanes.size()) i=0; i!=allPlanes.size(); i++) 182 for(decltype(allBurgers.size()) j=0; j!=allBurgers.size(); j++) 183 if(this->ScalProduct(allPlanes[i],allBurgers[j])==0) 184 allGSystems.push_back(GSystem(allBurgers[j],allPlanes[i])); 185 186 } 187 188 //=============================================================== 189 // Crystallo::SameGlideSystem 190 //--------------------------------------------------------------- 191 //! Determines a glide system belongs to a given familly 192 //--------------------------------------------------------------- 193 /*! 194 This routine determines whether a glide system defined as 195 \f${iplane1}[iburgers1]\f$ belongs to a glide system family 196 defined as \f${iburgers0}<iburgers0>\f$. 197 198 This routine is virtual. By default, this routine does not 199 include any symetry. 200 201 \param iplane0 reference glide system 202 \param iburgers0 reference burgers vector 203 \param iplane1 a specific glide system 204 \param iburgers1 a specific burgers vector 205 \return true if \f$()[]\f$ belongs to \f${}<>\f$ 206 */ 207 //=============================================================== SameGlideSystem(const IPlane & iplane0,const IBurgers & iburgers0,const IPlane & iplane1,const IBurgers & iburgers1) const208 bool Crystallo::SameGlideSystem(const IPlane& iplane0, 209 const IBurgers& iburgers0, 210 const IPlane& iplane1, 211 const IBurgers& iburgers1) const 212 { 213 return (iplane1==iplane0 && Coincide(iburgers0,iburgers1)!=0); 214 } 215 216 //===================================================================== 217 // Crystallo::GenerateEquivalentIBurgers 218 //--------------------------------------------------------------------- 219 //! Provide a list of IBurgers equivalent to a given IBurgers 220 //--------------------------------------------------------------------- 221 /*! 222 \param iburgers original IBurgers 223 \param planes equivalent IBurgers 224 */ 225 //===================================================================== GenerateEquivalentIBurgers(const IBurgers & iburgers,std::vector<IBurgers> & eqiburgers) const226 void Crystallo::GenerateEquivalentIBurgers(const IBurgers& iburgers, 227 std::vector<IBurgers>& eqiburgers) const 228 { 229 230 //---------------- 231 // initialization 232 //---------------- 233 std::vector<int> indices(iburgers.getIndex()); 234 std::vector<std::vector<int> > equivalent; 235 236 //----------------------------- 237 // generate equivalent indices 238 //----------------------------- 239 this->GenerateEquivalentIndices(indices,equivalent); 240 241 //--------------------- 242 // convert to iburgers 243 //--------------------- 244 eqiburgers.clear(); 245 eqiburgers.reserve(equivalent.size()); 246 for(unsigned i=0; i<equivalent.size(); i++) 247 eqiburgers.push_back(IBurgers(equivalent[i])); 248 249 } 250 251 //===================================================================== 252 // Crystallo::GenerateEquivalentPlanes 253 //--------------------------------------------------------------------- 254 //! Provide a list of IPlanes equivalent to a given IPlane 255 //--------------------------------------------------------------------- 256 /*! 257 \param iplane original IPlane 258 \param planes equivalent iplanes 259 */ 260 //===================================================================== GenerateEquivalentPlanes(const IPlane & iplane,std::vector<IPlane> & planes) const261 void Crystallo::GenerateEquivalentPlanes(const IPlane& iplane, 262 std::vector<IPlane>& planes) const 263 { 264 265 //---------------- 266 // initialization 267 //---------------- 268 std::vector<int> indices(iplane.getIndex()); 269 std::vector<std::vector<int> > equivalent; 270 271 //----------------------------- 272 // generate equivalent indices 273 //----------------------------- 274 this->GenerateEquivalentIndices(indices,equivalent); 275 276 //------------------- 277 // convert to planes 278 //------------------- 279 planes.clear(); 280 planes.reserve(equivalent.size()); 281 for(unsigned i=0; i<equivalent.size(); i++) 282 planes.push_back(IPlane(equivalent[i])); 283 284 } 285 286 Crystallo::~Crystallo() = default; 287 288 } // end of namespace numodis 289