PSCF v1.1
SpaceSymmetry.h
1#ifndef PSCF_SPACE_SYMMETRY_H
2#define PSCF_SPACE_SYMMETRY_H
3
4/*
5* PSCF - Polymer Self-Consistent Field Theory
6*
7* Copyright 2016 - 2022, The Regents of the University of Minnesota
8* Distributed under the terms of the GNU General Public License.
9*/
10
11#include <pscf/math/IntVec.h>
12#include <util/math/Rational.h>
13#include <util/containers/FMatrix.h>
14#include <util/containers/FArray.h>
15#include <util/format/Int.h>
16
17#include <iostream>
18
19namespace Pscf {
20
21 using namespace Util;
22
23 template <int D> class SpaceSymmetry;
24
25 // Non-member function declarations
26
35 template <int D>
36 bool operator == (const SpaceSymmetry<D>& A, const SpaceSymmetry<D>& B);
37
46 template <int D>
47 bool operator != (const SpaceSymmetry<D>& A, const SpaceSymmetry<D>& B);
48
57 template <int D>
58 SpaceSymmetry<D>
59 operator * (const SpaceSymmetry<D>& A, const SpaceSymmetry<D>& B);
60
72 template <int D>
73 IntVec<D> operator * (const SpaceSymmetry<D>& S, const IntVec<D>& V);
74
86 template <int D>
87 IntVec<D> operator * (const IntVec<D>& V, const SpaceSymmetry<D>& S);
88
97 template <int D>
98 std::ostream& operator << (std::ostream& out, const SpaceSymmetry<D>& A);
99
108 template <int D>
109 std::istream& operator >> (std::istream& in, SpaceSymmetry<D>& A);
110
136 template <int D>
138 {
139
140 public:
141
144
147
154
158 SpaceSymmetry(const SpaceSymmetry<D>& other);
159
164
168 void normalize();
169
181 void shiftOrigin(Translation const & origin);
182
187
192
196 int determinant() const;
197
204 int& R(int i, int j);
205
212 int R(int i, int j) const;
213
219 Rational& t(int i);
220
226 Rational t(int i) const;
227
228 // Static method
229
233 static const SpaceSymmetry<D>& identity();
234
235 private:
236
244 Rotation R_;
245
249 Translation t_;
250
251 // Static member variables
252
254 static SpaceSymmetry<D> identity_;
255
257 static bool hasIdentity_;
258
260 static void makeIdentity();
261
262 // friends:
263
264 friend
265 bool operator == <> (const SpaceSymmetry<D>& A,
266 const SpaceSymmetry<D>& B);
267
268 friend
269 bool operator != <> (const SpaceSymmetry<D>& A,
270 const SpaceSymmetry<D>& B);
271
272 friend
274 operator * <> (const SpaceSymmetry<D>& A,
275 const SpaceSymmetry<D>& B);
276
277 friend
278 IntVec<D> operator * <> (const IntVec<D>& V,
279 const SpaceSymmetry<D>& S);
280
281 friend
282 IntVec<D> operator * <>(const SpaceSymmetry<D>& S, const IntVec<D>& V);
283
284 friend
285 std::ostream& operator << <> (std::ostream& out,
286 const SpaceSymmetry<D>& A);
287
288 friend
289 std::istream& operator >> <> (std::istream& in,
291
292 };
293
294 // Explicit specialization of members
295
296 template <>
298
299 template <>
301
302 template <>
304
305 template <>
307
308 template <>
310
311 template <>
313
314 // Inline method definitions
315
316 template <int D>
317 inline
319 { return !(A == B); }
320
321 /*
322 * Return an element of the matrix by reference.
323 */
324 template <int D>
325 inline
326 int& SpaceSymmetry<D>::R(int i, int j)
327 { return R_(i, j); }
328
329 /*
330 * Return an element of the matrix by value
331 */
332 template <int D>
333 inline
334 int SpaceSymmetry<D>::R(int i, int j) const
335 { return R_(i, j); }
336
337 /*
338 * Return an element of the translation vector by reference.
339 */
340 template <int D>
341 inline
343 { return t_[i]; }
344
345 /*
346 * Return an element of the translation vector by value
347 */
348 template <int D>
349 inline
351 { return t_[i]; }
352
353 /*
354 * Return the identity symmetry operation.
355 */
356 template <int D>
357 inline
359 {
360 if (!hasIdentity_) makeIdentity();
361 return identity_;
362 }
363
364 // Friend function template definitions
365
366 /*
367 * Equality operator.
368 */
369 template <int D>
371 {
372 int i, j;
373 for (i = 0; i < D; ++i) {
374 if (A.t_[i] != B.t_[i]) {
375 return false;
376 }
377 for (j = 0; j < D; ++j) {
378 if (A.R_(i, j) != B.R_(i,j)) {
379 return false;
380 }
381 }
382 }
383 return true;
384 }
385
386 /*
387 * Group multipication operator for SpaceSymmetry<D> objects.
388 */
389 template <int D>
392 {
394 int i, j, k;
395
396 // Compute rotation matrix (matrix product)
397 for (i = 0; i < D; ++i) {
398 for (j = 0; j < D; ++j) {
399 C.R_(i, j) = 0;
400 for (k = 0; k < D; ++k) {
401 C.R_(i, j) += A.R_(i, k)*B.R_(k, j);
402 }
403 }
404 }
405
406 // Compute translation vector
407 for (i = 0; i < D; ++i) {
408 C.t_[i] = A.t_[i];
409 }
410 for (i = 0; i < D; ++i) {
411 for (j = 0; j < D; ++j) {
412 C.t_[i] += A.R_(i, j)*B.t_[j];
413 }
414 }
415 C.normalize();
416
417 return C;
418 }
419
420 /*
421 * Matrix / IntVec<D> multiplication.
422 */
423 template <int D>
425 {
426 IntVec<D> U;
427 int i, j;
428 for (i = 0; i < D; ++i) {
429 U[i] = 0;
430 for (j = 0; j < D; ++j) {
431 U[i] += S.R_(i,j)*V[j];
432 }
433 }
434 return U;
435 }
436
437 /*
438 * IntVec<D> / Matrix multiplication.
439 */
440 template <int D>
442 {
443 IntVec<D> U;
444 int i, j;
445 for (i = 0; i < D; ++i) {
446 U[i] = 0;
447 for (j = 0; j < D; ++j) {
448 U[i] += V[j]*S.R_(j,i);
449 }
450 }
451 return U;
452 }
453
454 /*
455 * Output stream inserter for a SpaceSymmetry<D>.
456 */
457 template <int D>
458 std::ostream& operator << (std::ostream& out, const SpaceSymmetry<D>& A)
459 {
460 int i, j;
461 for (i = 0; i < D; ++i) {
462 for (j = 0; j < D; ++j) {
463 out << " " << Int(A.R_(i,j),2);
464 }
465 out << std::endl;
466 }
467 for (i = 0; i < D; ++i) {
468 out << " " << A.t_[i];
469 }
470 out << std::endl;
471 return out;
472 }
473
474 /*
475 * Input stream extractor for a SpaceSymmetry<D>.
476 */
477 template <int D>
478 std::istream& operator >> (std::istream& in, SpaceSymmetry<D>& A)
479 {
480 int i, j;
481 for (i = 0; i < D; ++i) {
482 for (j = 0; j < D; ++j) {
483 in >> A.R_(i,j);
484 }
485 }
486 for (i = 0; i < D; ++i) {
487 in >> A.t_[i];
488 }
489 return in;
490 }
491
492 // Define static members
493 template<int D>
495
496 template<int D>
498
499
500 #ifndef PSCF_SPACE_SYMMETRY_TPP
501 // Suppress implicit instantiation
502 extern template class SpaceSymmetry<1>;
503 extern template class SpaceSymmetry<2>;
504 extern template class SpaceSymmetry<3>;
505 #endif
506
507}
508#endif
An IntVec<D, T> is a D-component vector of elements of integer type T.
Definition: IntVec.h:27
A SpaceSymmetry represents a crystallographic space group symmetry.
int determinant() const
Compute and return the determinant of the rotation matrix.
void normalize()
Shift components of translation to [0,1).
SpaceSymmetry< D >::Rotation inverseRotation() const
Compute and return the inverse of the rotation matrix.
SpaceSymmetry< D > inverse() const
Compute and return the inverse of this symmetry element.
SpaceSymmetry< D > & operator=(const SpaceSymmetry< D > &other)
Assignment operator.
FMatrix< int, D, D > Rotation
Typedef for matrix used to represent point group operation.
void shiftOrigin(Translation const &origin)
Shift the origin of space used in the coordinate system.
Rational & t(int i)
Return a component of the translation by reference.
FArray< Rational, D > Translation
Typedef for vector used to represent fractional translation.
static const SpaceSymmetry< D > & identity()
Return the identity element.
SpaceSymmetry()
Default constructor.
int & R(int i, int j)
Return an element of the matrix by reference.
A fixed size (static) contiguous array template.
Definition: FArray.h:47
Fixed Size Matrix.
Definition: FMatrix.h:29
Wrapper for an int, for formatted ostream output.
Definition: Int.h:37
A Rational number (a ratio of integers).
Definition: Rational.h:34
C++ namespace for polymer self-consistent field theory (PSCF).
Utility classes for scientific computation.
Definition: accumulators.mod:1
Rational operator*(Rational const &a, Rational const &b)
Compute product of rationals.
Definition: Rational.h:573
bool operator==(Polynomial< T > const &a, Polynomial< T > const &b)
Equality operator for polynomials.
Definition: Polynomial.h:675
std::istream & operator>>(std::istream &in, Pair< Data > &pair)
Input a Pair from an istream.
Definition: Pair.h:44
std::ostream & operator<<(std::ostream &out, const Pair< Data > &pair)
Output a Pair to an ostream, without line breaks.
Definition: Pair.h:57
bool operator!=(Polynomial< T > const &a, Polynomial< T > const &b)
Inequality operator for polynomials.
Definition: Polynomial.h:694