Mantid
Loading...
Searching...
No Matches
ReducedCell.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7/* File: ReducedCell.cpp */
8
10#include "MantidKernel/V3D.h"
11#include <stdexcept>
12
13namespace Mantid::Geometry {
15
21static const double transforms[ReducedCell::NUM_CELL_TYPES + 1][3][3] = // row
22 {{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // 0
23
24 {{1, -1, 1}, {1, 1, -1}, {-1, 1, 1}}, // 1
25 {{1, -1, 0}, {-1, 0, 1}, {-1, -1, -1}}, // 2
26 {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // 3
27 {{1, -1, 0}, {-1, 0, 1}, {-1, -1, -1}}, // 4
28 {{1, 0, 1}, {1, 1, 0}, {0, 1, 1}}, // 5
29
30 {{0, 1, 1}, {1, 0, 1}, {1, 1, 0}}, // 6
31 {{1, 0, 1}, {1, 1, 0}, {0, 1, 1}}, // 7
32 {{-1, -1, 0}, {-1, 0, -1}, {0, -1, -1}}, // 8
33 {{1, 0, 0}, {-1, 1, 0}, {-1, -1, 3}}, // 9
34 {{1, 1, 0}, {1, -1, 0}, {0, 0, -1}}, // 10
35
36 {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // 11
37 {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // 12
38 {{1, 1, 0}, {-1, 1, 0}, {0, 0, 1}}, // 13
39 {{1, 1, 0}, {-1, 1, 0}, {0, 0, 1}}, // 14
40 {{1, 0, 0}, {0, 1, 0}, {1, 1, 2}}, // 15
41
42 {{-1, -1, 0}, {1, -1, 0}, {1, 1, 2}}, // 16
43 {{-1, 0, -1}, {-1, -1, 0}, {0, 1, 1}}, // 17
44 {{0, -1, 1}, {1, -1, -1}, {1, 0, 0}}, // 18
45 {{-1, 0, 0}, {0, -1, 1}, {-1, 1, 1}}, // 19
46 {{0, 1, 1}, {0, 1, -1}, {-1, 0, 0}}, // 20
47
48 {{0, 1, 0}, {0, 0, 1}, {1, 0, 0}}, // 21
49 {{0, 1, 0}, {0, 0, 1}, {1, 0, 0}}, // 22
50 {{0, 1, 1}, {0, -1, 1}, {1, 0, 0}}, // 23
51 {{1, 2, 1}, {0, -1, 1}, {1, 0, 0}}, // 24
52 {{0, 1, 1}, {0, -1, 1}, {1, 0, 0}}, // 25
53
54 {{1, 0, 0}, {-1, 2, 0}, {-1, 0, 2}}, // 26
55 {{0, -1, 1}, {-1, 0, 0}, {1, -1, -1}}, // 27
56 {{-1, 0, 0}, {-1, 0, 2}, {0, 1, 0}}, // 28
57 {{1, 0, 0}, {1, -2, 0}, {0, 0, -1}}, // 29
58 {{0, 1, 0}, {0, 1, -2}, {-1, 0, 0}}, // 30
59
60 {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // 31
61 {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // 32
62 {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // 33
63 {{-1, 0, 0}, {0, 0, -1}, {0, -1, 0}}, // 34
64 {{0, -1, 0}, {-1, 0, 0}, {0, 0, -1}}, // 35
65
66 {{1, 0, 0}, {-1, 0, -2}, {0, 1, 0}}, // 36
67 {{1, 0, 2}, {1, 0, 0}, {0, 1, 0}}, // 37
68 {{-1, 0, 0}, {1, 2, 0}, {0, 0, -1}}, // 38
69 {{-1, -2, 0}, {-1, 0, 0}, {0, 0, -1}}, // 39
70 {{0, -1, 0}, {0, 1, 2}, {-1, 0, 0}}, // 40
71
72 {{0, -1, -2}, {0, -1, 0}, {-1, 0, 0}}, // 41
73 {{-1, 0, 0}, {0, -1, 0}, {1, 1, 2}}, // 42
74 {{-1, 0, 0}, {-1, -1, -2}, {0, -1, 0}}, // 43
75 {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}}; // 44
76
81static const double transform_modifier[2][3][3] = {{{0, 0, -1}, {0, 1, 0}, {1, 0, 1}}, // 0
82 {{-1, 0, -1}, {0, 1, 0}, {1, 0, 0}}}; // 1
83
89static const std::string lattice_types[ReducedCell::NUM_CELL_TYPES + 1] = {ReducedCell::NONE(), // 0
90
91 ReducedCell::CUBIC(), // 1
93 ReducedCell::CUBIC(), // 3
95 ReducedCell::CUBIC(), // 5
96
102
108
114
120
126
132
138
142 ReducedCell::TRICLINIC()}; // 44
143
149static const std::string center_types[ReducedCell::NUM_CELL_TYPES + 1] = {ReducedCell::NONE(), // 0
150
156
162
168
174
180
186
192
198
203
220ReducedCell::ReducedCell(size_t form_num, double a, double b, double c, double alpha, double beta, double gamma) {
221 if (a <= 0 || b <= 0 || c <= 0) {
222 throw std::invalid_argument("ReducedCell(): a, b, c, must be positive");
223 }
224 if (alpha <= 0 || alpha >= 180 || beta <= 0 || beta >= 180 || gamma <= 0 || gamma >= 180) {
225 throw std::invalid_argument("ReducedCell(): alpha, beta, gamma, must be between 0 and 180 degrees");
226 }
227
228 alpha = alpha * M_PI / 180;
229 beta = beta * M_PI / 180;
230 gamma = gamma * M_PI / 180;
231
232 init(form_num, a * a, b * b, c * c, b * c * cos(alpha), a * c * cos(beta), a * b * cos(gamma));
233}
234
242void ReducedCell::init(size_t f_num, double a_a, double b_b, double c_c, double b_c, double a_c, double a_b) {
243 if (f_num > NUM_CELL_TYPES) {
244 throw std::invalid_argument("Reduced form number must be no more than 44");
245 }
246 // The mixed dot products should be > 0 for + cell
247 // types and always appear inside absolute value
248 // for - cell types, therefore we can deal with
249 // the absolute value for all rows in the table.
250 if (f_num > 0) {
251 b_c = fabs(b_c);
252 a_c = fabs(a_c);
253 a_b = fabs(a_b);
254 }
255
256 form_num = f_num;
257
258 transform = DblMatrix(3, 3, false);
259 for (size_t row = 0; row < 3; row++)
260 for (size_t col = 0; col < 3; col++) {
261 transform[row][col] = transforms[f_num][row][col];
262 }
265
266 if (form_num == 0) {
267 scalars[0] = a_a;
268 scalars[1] = b_b;
269 scalars[2] = c_c;
270 } else if (form_num <= 8) {
271 scalars[0] = a_a;
272 scalars[1] = a_a;
273 scalars[2] = a_a;
274 } else if (form_num <= 17) {
275 scalars[0] = a_a;
276 scalars[1] = a_a;
277 scalars[2] = c_c;
278 } else if (form_num <= 25) {
279 scalars[0] = a_a;
280 scalars[1] = b_b;
281 scalars[2] = b_b;
282 } else {
283 scalars[0] = a_a;
284 scalars[1] = b_b;
285 scalars[2] = c_c;
286 }
287
288 double value;
289 switch (form_num) {
290 case 0:
291 scalars[3] = b_c;
292 scalars[4] = a_c;
293 scalars[5] = a_b;
294 break;
295 case 1:
296 scalars[3] = a_a / 2;
297 scalars[4] = a_a / 2;
298 scalars[5] = a_a / 2;
299 break;
300 case 2:
301 scalars[3] = b_c;
302 scalars[4] = b_c;
303 scalars[5] = b_c;
304 break;
305 case 3:
306 scalars[3] = 0;
307 scalars[4] = 0;
308 scalars[5] = 0;
309 break;
310 case 4:
311 value = -fabs(b_c);
312 scalars[3] = value;
313 scalars[4] = value;
314 scalars[5] = value;
315 break;
316 case 5:
317 scalars[3] = -a_a / 3;
318 scalars[4] = -a_a / 3;
319 scalars[5] = -a_a / 3;
320 break;
321 case 6:
322 value = (-a_a + fabs(a_b)) / 2;
323 scalars[3] = value;
324 scalars[4] = value;
325 scalars[5] = -fabs(a_b);
326 ;
327 break;
328 case 7:
329 value = (-a_a + fabs(b_c)) / 2;
330 scalars[3] = -fabs(b_c);
331 scalars[4] = value;
332 scalars[5] = value;
333 break;
334 case 8:
335 scalars[3] = -fabs(b_c);
336 scalars[4] = -fabs(a_c);
337 scalars[5] = -(fabs(a_a) - fabs(b_c) - fabs(a_c));
338 break;
339 case 9:
340 scalars[3] = a_a / 2;
341 scalars[4] = a_a / 2;
342 scalars[5] = a_a / 2;
343 break;
344 case 10:
345 scalars[3] = b_c;
346 scalars[4] = b_c;
347 scalars[5] = a_b;
348 foot_note_d(c_c, b_c);
349 break;
350 case 11:
351 scalars[3] = 0;
352 scalars[4] = 0;
353 scalars[5] = 0;
354 break;
355 case 12:
356 scalars[3] = 0;
357 scalars[4] = 0;
358 scalars[5] = -a_a / 2;
359 break;
360 case 13:
361 scalars[3] = 0;
362 scalars[4] = 0;
363 scalars[5] = -fabs(a_b);
364 break;
365 case 14:
366 value = -fabs(b_c);
367 scalars[3] = value;
368 scalars[4] = value;
369 scalars[5] = -fabs(a_b);
370 foot_note_d(c_c, b_c);
371 break;
372 case 15:
373 scalars[3] = -a_a / 2;
374 scalars[4] = -a_a / 2;
375 scalars[5] = 0;
376 break;
377 case 16:
378 value = -fabs(b_c);
379 scalars[3] = value;
380 scalars[4] = value;
381 scalars[5] = -(a_a - 2 * fabs(b_c));
382 break;
383 case 17:
384 scalars[3] = -fabs(b_c);
385 scalars[4] = -fabs(a_c);
386 scalars[5] = -(a_a - fabs(b_c) - fabs(a_c));
387 foot_note_e(a_a, c_c, a_c);
388 break;
389 case 18:
390 scalars[3] = a_a / 4;
391 scalars[4] = a_a / 2;
392 scalars[5] = a_a / 2;
393 break;
394 case 19:
395 scalars[3] = b_c;
396 scalars[4] = a_a / 2;
397 scalars[5] = a_a / 2;
398 break;
399 case 20:
400 scalars[3] = b_c;
401 scalars[4] = a_c;
402 scalars[5] = a_c;
403 foot_note_b(a_a, a_c);
404 break;
405 case 21:
406 scalars[3] = 0;
407 scalars[4] = 0;
408 scalars[5] = 0;
409 break;
410 case 22:
411 scalars[3] = -b_b / 2;
412 scalars[4] = 0;
413 scalars[5] = 0;
414 break;
415 case 23:
416 scalars[3] = -fabs(b_c);
417 scalars[4] = 0;
418 scalars[5] = 0;
419 break;
420 case 24:
421 scalars[3] = -(b_b - a_a / 3) / 2;
422 scalars[4] = -a_a / 3;
423 scalars[5] = -a_a / 3;
424 break;
425 case 25:
426 value = -fabs(a_c);
427 scalars[3] = -fabs(b_c);
428 scalars[4] = value;
429 scalars[5] = value;
430 foot_note_b(a_a, a_c);
431 break;
432 case 26:
433 scalars[3] = a_a / 4;
434 scalars[4] = a_a / 2;
435 scalars[5] = a_a / 2;
436 break;
437 case 27:
438 scalars[3] = b_c;
439 scalars[4] = a_a / 2;
440 scalars[5] = a_a / 2;
441 foot_note_f(b_b, c_c, b_c);
442 break;
443 case 28:
444 scalars[3] = a_b / 2;
445 scalars[4] = a_a / 2;
446 scalars[5] = a_b;
447 break;
448 case 29:
449 scalars[3] = a_c / 2;
450 scalars[4] = a_c;
451 scalars[5] = a_a / 2;
452 break;
453 case 30:
454 scalars[3] = b_b / 2;
455 scalars[4] = a_b / 2;
456 scalars[5] = a_b;
457 break;
458 case 31:
459 scalars[3] = b_c;
460 scalars[4] = a_c;
461 scalars[5] = a_b;
462 break;
463 case 32:
464 scalars[3] = 0;
465 scalars[4] = 0;
466 scalars[5] = 0;
467 break;
468 case 33:
469 scalars[3] = 0;
470 scalars[4] = -fabs(a_c);
471 scalars[5] = 0;
472 break;
473 case 34:
474 scalars[3] = 0;
475 scalars[4] = 0;
476 scalars[5] = -fabs(a_b);
477 break;
478 case 35:
479 scalars[3] = -fabs(b_c);
480 scalars[4] = 0;
481 scalars[5] = 0;
482 break;
483 case 36:
484 scalars[3] = 0;
485 scalars[4] = -a_a / 2;
486 scalars[5] = 0;
487 break;
488 case 37:
489 scalars[3] = -fabs(b_c);
490 scalars[4] = -a_a / 2;
491 scalars[5] = 0;
492 foot_note_c(b_b, b_c);
493 break;
494 case 38:
495 scalars[3] = 0;
496 scalars[4] = 0;
497 scalars[5] = -a_a / 2;
498 break;
499 case 39:
500 scalars[3] = -fabs(b_c);
501 scalars[4] = 0;
502 scalars[5] = -a_a / 2;
503 foot_note_d(c_c, b_c);
504 break;
505 case 40:
506 scalars[3] = -b_b / 2;
507 scalars[4] = 0;
508 scalars[5] = 0;
509 break;
510 case 41:
511 scalars[3] = -b_b / 2;
512 scalars[4] = -fabs(a_c);
513 scalars[5] = 0;
514 foot_note_b(a_a, a_c);
515 break;
516 case 42:
517 scalars[3] = -b_b / 2;
518 scalars[4] = -a_a / 2;
519 scalars[5] = 0;
520 break;
521 case 43:
522 scalars[3] = -(b_b - fabs(a_b)) / 2;
523 scalars[4] = -(a_a - fabs(a_b)) / 2;
524 scalars[5] = -fabs(a_b);
525 break;
526 case 44:
527 scalars[3] = -fabs(b_c);
528 scalars[4] = -fabs(a_c);
529 scalars[5] = -fabs(a_b);
530 break;
531 }
532}
533
537void ReducedCell::foot_note_b(double a_a, double a_c) {
538 if (a_a < 4 * fabs(a_c)) // foot note b
539 {
540 premultiply(0); // use matrix modification 0
542 }
543}
544
548void ReducedCell::foot_note_c(double b_b, double b_c) {
549 if (b_b < 4 * fabs(b_c)) // foot note c
550 {
551 premultiply(0); // use matrix modification 0
553 }
554}
555
559void ReducedCell::foot_note_d(double c_c, double b_c) {
560 if (c_c < 4 * fabs(b_c)) // foot note d
561 {
562 premultiply(0); // use matrix modification 0
564 }
565}
566
570void ReducedCell::foot_note_e(double a_a, double c_c, double a_c) {
571 if (3 * a_a < c_c + 2 * fabs(a_c)) // foot note e
572 {
573 premultiply(1); // use matrix modification 1
575 }
576}
577
581void ReducedCell::foot_note_f(double b_b, double c_c, double b_c) {
582 if (3 * b_b < c_c + 2 * fabs(b_c)) // foot note f
583 {
584 premultiply(1); // use matrix modification 1
586 }
587}
588
594 DblMatrix modifier = DblMatrix(3, 3, false);
595 for (size_t row = 0; row < 3; row++)
596 for (size_t col = 0; col < 3; col++) {
597 modifier[row][col] = transform_modifier[index][row][col];
598 }
599 transform = modifier * transform;
600}
601
605size_t ReducedCell::GetFormNum() const { return form_num; }
606
610std::string ReducedCell::GetCellType() const { return std::string(cell_type); }
611
617std::string ReducedCell::GetCentering() const { return std::string(centering); }
618
631double ReducedCell::WeightedDistance(const ReducedCell &other) const {
632 std::vector<double> vals_1 = norm_vals(*this);
633 std::vector<double> vals_2 = norm_vals(other);
634
635 double max = 0;
636
637 for (size_t i = 0; i < vals_1.size(); i++) {
638 double difference = fabs(vals_1[i] - vals_2[i]);
639 if (difference > max)
640 max = difference;
641 }
642 return max;
643}
644
652std::vector<double> ReducedCell::norm_vals(const ReducedCell &info) const {
653 std::vector<double> vals;
654 vals.resize(6);
655
656 double a = sqrt(info.scalars[0]);
657 double b = sqrt(info.scalars[1]);
658 double c = sqrt(info.scalars[2]);
659
660 // Use the side lengths themselves, instead of squares of sides
661 // so errors correspond to errors in lattice positions
662 vals[0] = a;
663 vals[1] = b;
664 vals[2] = c;
665 // Use law of cosines to interpret errors in dot products
666 // interms of errors in lattice positions.
667 vals[3] = sqrt((b * b + c * c - 2 * info.scalars[3]));
668 vals[4] = sqrt((a * a + c * c - 2 * info.scalars[4]));
669 vals[5] = sqrt((a * a + b * b - 2 * info.scalars[5]));
670 return vals;
671}
672
681
682} // namespace Mantid::Geometry
double value
The value of the point.
Definition: FitMW.cpp:51
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
#define fabs(x)
Definition: Matrix.cpp:22
Instances of this class represent information about reduced cell types including the transformation r...
Definition: ReducedCell.h:32
std::string GetCellType() const
Get the cell type of this form.
void init(size_t f_num, double a_a, double b_b, double c_c, double b_c, double a_c, double a_b)
Initialize all private data to represent one row of Table 2, for the row specified by the form number...
void foot_note_b(double a_a, double a_c)
Adjust tranform and centering according to foot note b of the paper.
static const std::string HEXAGONAL()
Definition: ReducedCell.h:53
Kernel::DblMatrix GetTransformation()
Return the transformation to map the reduced cell to the conventional cell, as listed in Table 2,...
Kernel::DblMatrix transform
Definition: ReducedCell.h:79
double WeightedDistance(const ReducedCell &other) const
Get the maximum absolute weighted difference between the scalars for the specifed ReducedCellInfo obj...
void foot_note_f(double b_b, double c_c, double b_c)
Adjust tranform and centering according to foot note f of the paper.
static const std::string MONOCLINIC()
Definition: ReducedCell.h:57
static const std::string RHOMBOHEDRAL()
Definition: ReducedCell.h:54
void foot_note_c(double b_b, double b_c)
Adjust tranform and centering according to foot note c of the paper.
static const std::string CUBIC()
Definition: ReducedCell.h:52
static const std::string F_CENTERED()
Definition: ReducedCell.h:61
static const std::string TRICLINIC()
Definition: ReducedCell.h:58
std::vector< double > norm_vals(const ReducedCell &info) const
Get list of six values, related to the six scalars, but adjusted so that changes in these values repr...
static const std::string NONE()
Definition: ReducedCell.h:51
static const std::string R_CENTERED()
Definition: ReducedCell.h:65
ReducedCell(size_t form_num=0, double a=1, double b=1, double c=1, double alpha=90, double beta=90, double gamma=90)
Construct a ReducedCell object representing the specified row of Table 2 for a reduced cell with the ...
std::string GetCentering() const
Get centering assigned to this form.
void foot_note_d(double c_c, double b_c)
Adjust tranform and centering according to foot note d of the paper.
void premultiply(size_t index)
Adjust the tranformation for this reduced cell by premultiplying by modification transform 0 or 1.
void foot_note_e(double a_a, double c_c, double a_c)
Adjust tranform and centering according to foot note e of the paper.
static const std::string TETRAGONAL()
Definition: ReducedCell.h:55
static const std::string ORTHORHOMBIC()
Definition: ReducedCell.h:56
size_t GetFormNum() const
Get the form number used to construct this form.
static const std::string P_CENTERED()
Definition: ReducedCell.h:64
static const std::string I_CENTERED()
Definition: ReducedCell.h:62
static const std::string C_CENTERED()
Definition: ReducedCell.h:63
static const std::string center_types[ReducedCell::NUM_CELL_TYPES+1]
Array of Strings specifying the centering for reduced cells for rows 1 to 44 of Table 2.
static const double transform_modifier[2][3][3]
These transforms pre-multiply the basic transforms in certain cases, as listed in the footnotes to Ta...
Definition: ReducedCell.cpp:81
static const double transforms[ReducedCell::NUM_CELL_TYPES+1][3][3]
Array of basic transformations from reduced cell to conventional cell for rows 1 to 44 of Table 2.
Definition: ReducedCell.cpp:21
static const std::string lattice_types[ReducedCell::NUM_CELL_TYPES+1]
Array of Strings specifying the cell type for reduced cells for rows 1 to 44 of Table 2.
Definition: ReducedCell.cpp:89
Mantid::Kernel::Matrix< double > DblMatrix
Definition: Matrix.h:206