Develop and Download Open Source Software

Browse Subversion Repository

Contents of /BLDConograph_ver1/trunk/src/lattice_symmetry/LatticeFigureOfMerit.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 32 - (show annotations) (download) (as text)
Sat Aug 6 01:34:09 2016 UTC (7 years, 7 months ago) by rtomiyasu
File MIME type: text/x-c++src
File size: 11976 byte(s)
Monoclinic(B) -> Monoclinic(C)
1 /*
2 * The MIT License
3
4 BLDConograph (Bravais lattice determination module in Conograph)
5
6 Copyright (c) <2012> <Ryoko Oishi-Tomiyasu, KEK>
7
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 THE SOFTWARE.
25 *
26 */
27 #include "../utility_data_structure/FracMat.hh"
28 #include "../utility_lattice_reduction/put_Selling_reduced_lattice.hh"
29 #include "../utility_lattice_reduction/put_Buerger_reduced_lattice.hh"
30 #include "ReducedLatticeToCheckBravais.hh"
31 #include "LatticeFigureOfMerit.hh"
32
33 const NRMat<Int4> LatticeFigureOfMerit::m_tmat_prim_to_face = put_transform_matrix_row3to4( transpose( BravaisType::putTransformMatrixFromPrimitiveToFace() ) );
34 const NRMat<Int4> LatticeFigureOfMerit::m_tmat_prim_to_body = put_transform_matrix_row3to4( BravaisType::putTransformMatrixFromBodyToPrimitive() );
35 const NRMat<Int4> LatticeFigureOfMerit::m_tmat_prim_to_rhomhex = put_transform_matrix_row3to4( transpose( BravaisType::putTransformMatrixFromPrimitiveToRhomHex() ) );
36 const NRMat<Int4> LatticeFigureOfMerit::m_tmat_prim_to_base[3] =
37 {
38 put_transform_matrix_row3to4( transpose( BravaisType::putTransformMatrixFromPrimitiveToBase(BaseA_Axis) ) ),
39 put_transform_matrix_row3to4( transpose( BravaisType::putTransformMatrixFromPrimitiveToBase(BaseB_Axis) ) ),
40 put_transform_matrix_row3to4( transpose( BravaisType::putTransformMatrixFromPrimitiveToBase(BaseC_Axis) ) )
41 };
42 const NRMat<Int4> LatticeFigureOfMerit::m_tmat_prim_to_prim = put_transform_matrix_row3to4();
43
44 LatticeFigureOfMerit::LatticeFigureOfMerit()
45 : m_S_red(3)
46 {
47 }
48
49
50 LatticeFigureOfMerit::LatticeFigureOfMerit(const BravaisType& brat,
51 const SymMat43_Double& S)
52 : m_S_red(3)
53 {
54 this->setLatticeConstants43(brat, S);
55 }
56
57 #ifdef DEBUG
58 static bool checkInitialLatticeParameters(
59 const BravaisType& brat,
60 const SymMat<Double>& S_red)
61 {
62 const SymMat<Double> inv_S_red( Inverse3(S_red) );
63
64 if( brat.enumPointGroup() == C2h_Y && brat.enumCentringType() == Prim )
65 {
66 assert( inv_S_red(0,2) <= 0.0 &&
67 inv_S_red(0,0) * 0.9999 < inv_S_red(2,2)
68 && fabs( inv_S_red(0,2) ) * 1.9999 < inv_S_red(2,2)
69 && fabs( inv_S_red(0,2) ) * 1.9999 < inv_S_red(0,0) );
70 }
71 else if( brat.enumPointGroup() == C2h_Z && brat.enumCentringType() == Prim )
72 {
73 assert( inv_S_red(0,1) <= 0.0
74 && inv_S_red(0,0) * 0.9999 < inv_S_red(1,1)
75 && fabs( inv_S_red(0,1) ) * 1.9999 < inv_S_red(0,0)
76 && fabs( inv_S_red(0,1) ) * 1.9999 < inv_S_red(1,1) );
77 }
78 else if( brat.enumPointGroup() == C2h_X && brat.enumCentringType() == Prim )
79 {
80 assert( inv_S_red(1,2) <= 0.0
81 && inv_S_red(1,1) * 0.9999 < inv_S_red(2,2)
82 && fabs( inv_S_red(1,2) ) * 1.9999 < inv_S_red(1,1)
83 && fabs( inv_S_red(1,2) ) * 1.9999 < inv_S_red(2,2) );
84 }
85 else if( brat.enumPointGroup() == C2h_Y && brat.enumCentringType() == BaseZ )
86 {
87 assert( inv_S_red(0,2) <= 0.0
88 && fabs( inv_S_red(0,2) ) * 0.9999 < inv_S_red(2,2)
89 && fabs( inv_S_red(0,2) ) * 1.9999 < inv_S_red(0,0) );
90 }
91 else if( brat.enumPointGroup() == C2h_Z && brat.enumCentringType() == BaseX )
92 {
93 assert( inv_S_red(0,1) <= 0.0
94 && fabs( inv_S_red(0,1) ) * 0.9999 < inv_S_red(0,0)
95 && fabs( inv_S_red(0,1) ) * 1.9999 < inv_S_red(1,1) );
96 }
97 else if( brat.enumPointGroup() == C2h_X && brat.enumCentringType() == BaseY )
98 {
99 assert( inv_S_red(1,2) <= 0.0
100 && fabs( inv_S_red(1,2) ) * 0.9999 < inv_S_red(1,1)
101 && fabs( inv_S_red(1,2) ) * 1.9999 < inv_S_red(2,2) );
102 }
103 else if( brat.enumBravaisType() == Orthorhombic_C )
104 {
105 assert( brat.enumCentringType() == BaseZ );
106 assert( inv_S_red(0,0) * 0.9999 < inv_S_red(1,1) );
107 }
108 else if( brat.enumPointGroup() == D2h && brat.enumCentringType() == Prim )
109 {
110 assert( inv_S_red(0,0) * 0.9999 < inv_S_red(1,1)
111 && inv_S_red(1,1) * 0.9999 < inv_S_red(2,2) );
112 }
113 return true;
114 }
115 #endif
116
117 static void putTransformMatrixToBuergerReduced(
118 const SymMat<Double>& S, NRMat<Int4>& trans_mat)
119 {
120 assert( S.size() == 3 );
121
122 SymMat<Double> S_super_obtuse(4);
123 put_Selling_reduced_dim_3(S, S_super_obtuse, trans_mat);
124 moveSmallerDiagonalLeftUpper(S_super_obtuse, trans_mat);
125
126 // S_red = trans_mat * S_super_obtuse * transpose(trans_mat).
127 SymMat<Double> S_red(3);
128 NRMat<Int4> trans_mat2;
129 putBuergerReducedMatrix(S_super_obtuse, S_red, trans_mat2);
130 trans_mat = mprod( trans_mat2, put_transform_matrix_row4to3(trans_mat) );
131 }
132
133
134 void LatticeFigureOfMerit::setInverseOfBuergerReducedForm(NRMat<Int4>& trans_mat, const SymMat43_Double& S_optimized)
135 {
136 if( m_brat.enumBravaisType() == Triclinic )
137 {
138 // trans_mat * Inverse(S_optimized.first) * transpose(trans_mat) is Buerger-reduced
139 // <=> Inverse of transpose(Inverse(trans_mat)) * S_optimized.first * Inverse(trans_mat) is Buerger-reduced.
140 putTransformMatrixToBuergerReduced(Inverse3(S_optimized.first), trans_mat);
141 transpose_square_matrix(trans_mat);
142 m_S_red = transform_sym_matrix(Inverse3(trans_mat), S_optimized.first);
143 }
144 else
145 {
146 m_S_red = S_optimized.first;
147 trans_mat = identity_matrix<Int4>(3);
148 if( m_brat.enumBravaisType() == Monoclinic_P )
149 {
150 if( m_brat.enumPointGroup() == C2h_X )
151 {
152 putBuergerReducedMonoclinicP(1, 2, m_S_red, trans_mat);
153 }
154 else if( m_brat.enumPointGroup() == C2h_Y )
155 {
156 putBuergerReducedMonoclinicP(0, 2, m_S_red, trans_mat);
157 }
158 else //if( m_brat.enumPointGroup() == C2h_Z )
159 {
160 putBuergerReducedMonoclinicP(0, 1, m_S_red, trans_mat);
161 }
162 }
163 else if( m_brat.enumBravaisType() == Monoclinic_B )
164 {
165 m_S_red = S_optimized.first;
166 putBuergerReducedMonoclinicB(m_brat, m_S_red, trans_mat);
167 }
168 else if( m_brat.enumPointGroup() == D2h )
169 {
170 m_S_red = S_optimized.first;
171 putBuergerReducedOrthorhombic(m_brat.enumCentringType(), m_S_red, trans_mat);
172 }
173 }
174
175 assert( checkInitialLatticeParameters(m_brat, m_S_red) );
176 }
177
178
179 void LatticeFigureOfMerit::setLatticeConstants43(const BravaisType& brat, const SymMat43_Double& S)
180 {
181 m_brat = brat;
182
183 NRMat<Int4> trans_mat;
184 setInverseOfBuergerReducedForm(trans_mat, S); // Set m_S_red from S.
185 }
186
187 ZErrorMessage LatticeFigureOfMerit::setLatticeConstants(const BravaisType& brat, const SymMat<Double>& Sval)
188 {
189 assert( Sval.size()==3 );
190
191 SymMat43_Double S_red_optimized = SymMat43_Double(Sval, NRMat<Int4>(4,3));
192 cal_average_crystal_system(brat.enumPointGroup(), S_red_optimized.first);
193 if( brat.enumCentringType() == Face )
194 {
195 S_red_optimized.second = m_tmat_prim_to_face;
196 }
197 else if( brat.enumCentringType() == Inner )
198 {
199 S_red_optimized.second = m_tmat_prim_to_body;
200 }
201 else if( brat.enumCentringType() == BaseX
202 || brat.enumCentringType() == BaseY
203 || brat.enumCentringType() == BaseZ )
204 {
205 S_red_optimized.second = m_tmat_prim_to_base[ (size_t)brat.enumBASEaxis() ];
206 }
207 else if( brat.enumCentringType() == Rhom_hex )
208 {
209 S_red_optimized.second = m_tmat_prim_to_rhomhex;
210 }
211 else // if( brat.enumCentringType() == Prim )
212 {
213 S_red_optimized.second = m_tmat_prim_to_prim;
214 }
215
216 // S_super_obtuse = trans_mat * S_red.first * Transpose(trans_mat).
217 SymMat<Double> S_super_obtuse = transform_sym_matrix(S_red_optimized.second, S_red_optimized.first);
218 if( !put_Selling_reduced_dim_3(S_super_obtuse, S_red_optimized.second) )
219 {
220 return ZErrorMessage(ZErrorArgument, "The argument matrix is not positive definite" __FILE__, __LINE__, __FUNCTION__);
221 }
222 moveSmallerDiagonalLeftUpper(S_super_obtuse, S_red_optimized.second);
223
224 setLatticeConstants43(brat, S_red_optimized);
225
226 return ZErrorMessage();
227 }
228
229
230 inline bool checkIfFirstEntryIsPositive(const VecDat3<Int4>& rhs)
231 {
232 for(Int4 i=0; i<3; i++)
233 {
234 if( rhs[i] == 0 ) continue;
235 if( rhs[i] > 0 ) return true;
236 else return false;
237 }
238 return false;
239 }
240
241
242
243 void LatticeFigureOfMerit::printLatticeInformation(
244 const eABCaxis& abc_axis,
245 const eRHaxis& rh_axis,
246 const Int4& label_start0,
247 ostream* os) const
248 {
249 Int4 label_start = label_start0;
250 os->width(label_start);
251 *os << "" << "<CrystalSystem>";
252 os->width(17);
253 *os << put_bravais_type_name(this->enumBravaisType(), abc_axis);
254 *os << " </CrystalSystem>\n\n";
255
256 os->width(label_start); *os << "";
257 *os << "<!-- a, b, c(angstrom), alpha, beta, gamma(deg.)-->\n";
258
259 VecDat3<Double> length_axis, angle_axis;
260 if( this->enumBravaisType() == Rhombohedral )
261 {
262 this->putReducedLatticeConstantsDegree(abc_axis, Rho_Axis, length_axis, angle_axis);
263
264 os->width(label_start); *os << "";
265 *os << "<UnitCellParameters axis=\"Rhombohedral\">";
266 os->width(14);
267 *os << length_axis[0];
268 os->width(14);
269 *os << length_axis[1];
270 os->width(14);
271 *os << length_axis[2];
272 os->width(14);
273 *os << angle_axis[0];
274 os->width(14);
275 *os << angle_axis[1];
276 os->width(14);
277 *os << angle_axis [2];
278 *os << " </UnitCellParameters>\n";
279
280 this->putReducedLatticeConstantsDegree(abc_axis, Hex_Axis, length_axis, angle_axis);
281
282 os->width(label_start); *os << "";
283 *os << "<UnitCellParameters axis=\"Hexagonal\">";
284 os->width(14);
285 *os << length_axis[0];
286 os->width(14);
287 *os << length_axis[1];
288 os->width(14);
289 *os << length_axis[2];
290 os->width(14);
291 *os << angle_axis[0];
292 os->width(14);
293 *os << angle_axis[1];
294 os->width(14);
295 *os << angle_axis[2];
296 *os << " </UnitCellParameters>\n\n";
297 }
298 else
299 {
300 this->putReducedLatticeConstantsDegree(abc_axis, Rho_Axis, length_axis, angle_axis);
301
302 os->width(label_start); *os << "";
303 *os << "<UnitCellParameters>";
304 os->width(14);
305 *os << length_axis[0];
306 os->width(14);
307 *os << length_axis[1];
308 os->width(14);
309 *os << length_axis[2];
310 os->width(14);
311 *os << angle_axis[0];
312 os->width(14);
313 *os << angle_axis[1];
314 os->width(14);
315 *os << angle_axis[2];
316 *os << " </UnitCellParameters>\n";
317 }
318 }
319
320
321 void LatticeFigureOfMerit::putLatticeConstantsDegree(const BravaisType& brat, const SymMat<Double>& S0,
322 const eABCaxis& axis1,
323 const eRHaxis& axis2, VecDat3<Double>& length_axis, VecDat3<Double>& angle_axis)
324 {
325 SymMat<Double> S = S0;
326 if( brat.enumBravaisType() == Rhombohedral && axis2 != brat.enumRHaxis() )
327 {
328 if( axis2 == Hex_Axis ) // Rho -> Hex.
329 {
330 static const FracMat matrix_rho2hex = FInverse3( transpose(BravaisType::putTransformMatrixFromPrimitiveToRhomHex() ) );
331 S = transform_sym_matrix(matrix_rho2hex.mat, S)/(matrix_rho2hex.denom*matrix_rho2hex.denom);
332 }
333 else // if( axis2 == RhoAxis ) // Hex -> Rho.
334 {
335 static const NRMat<Int4> matrix_hex2rho = transpose( BravaisType::putTransformMatrixFromPrimitiveToRhomHex() );
336 S = transform_sym_matrix(matrix_hex2rho, S);
337 }
338 }
339 else if( brat.enumBravaisType() == Monoclinic_B )
340 {
341 const NRMat<Int4> this2output = put_transform_matrix_monoclinic_b(brat.enumABCaxis(), axis1);
342 S = transform_sym_matrix(this2output, S);
343 }
344
345 calLatticeConstant( S, length_axis, angle_axis );
346 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26