namespace ewalena  0.2.15
ewalena is not an acronym
include/ewalena/numerics/crystal_field_base.h
Go to the documentation of this file.
00001 // -------------------------------------------------------------------
00002 // @author Toby D. Young
00003 // @version $Id: crystal_field_base.h 988 2012-11-26 19:09:39Z oneliefleft $
00004 //
00005 // Copyright 2009, 2010, 2012 namespace ewalena authors. All rights
00006 // reserved.
00007 //
00008 // Redistribution and use in source and binary forms, with or without
00009 // modification, are permitted provided that the following conditions
00010 // are met:
00011 //
00012 // 1. Redistributions of source code must retain the above copyright
00013 //    notice, this list of conditions and the following disclaimer.
00014 //
00015 // 2. Redistributions in binary form must reproduce the above
00016 //    copyright notice, this list of conditions and the following
00017 //    disclaimer in the documentation and/or other materials provided
00018 //    with the distribution.
00019 //
00020 // THIS SOFTWARE IS PROVIDED BY THE NAMEPSACE EWALENA AUTHORS ``AS
00021 // IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024 // NAMESPACE EWALENA AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
00025 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00026 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00027 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00028 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00029 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00030 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
00031 // OF THE POSSIBILITY OF SUCH DAMAGE.
00032 //
00033 // The views and conclusions contained in the software and
00034 // documentation are those of the authors and should not be
00035 // interpreted as representing official policies, either expressed or
00036 // implied, of the namespace ewalena authors.
00037 // -------------------------------------------------------------------
00038 
00039 #ifndef __ewalena_crystal_field_base_h
00040 #define __ewalena_crystal_field_base_h
00041 
00042 #include <cassert>
00043 #include <map>
00044 #include <vector>
00045 
00046 #ifdef EWALENA_HAVE_CONFIG_H
00047 #include <ewalena/base/config.h>
00048 #endif
00049 
00050 #include <ewalena/lac/vector.h>
00051 #include <ewalena/lac/matrix.h>
00052 #include <ewalena/base/tensor.h>
00053 
00054 namespace ewalena
00055 {
00056   
00057   namespace Crystal
00058   {
00059     
00060     /* TODO: Investigate how a union can constructed to access
00061        combinations of flags using group number. */
00062     
00101     enum SymmetryFlag
00102     {
00103       
00108       null         = 0,     
00109       
00113       triclinic    = 0x0001,
00114       
00118       monoclinic   = 0x0002,
00119       
00123       orthorhombic = 0x0003, 
00124       
00128       tetragonal   = 0x0004, 
00129       
00133       trigonal     = 0x0005,     
00134       
00138       hexagonal    = 0x0006,     
00139       
00143       cubic        = 0x0007,
00144       
00145       
00149       k32          = 0x0035
00150       
00151     }; /* Crystal */
00152     
00153     
00154     
00155     /*-------------- Inline and Other Functions -----------------------*/  
00156     
00161     template <class STREAM>
00162       inline
00163       STREAM &operator << (STREAM &stream, const SymmetryFlag symmetry_flag)
00164       {
00165         stream << "   SymmetryFlag::Crystal ";
00166         
00167         if (symmetry_flag &SymmetryFlag::null)         stream << "null";
00168         
00169         if (symmetry_flag &SymmetryFlag::triclinic)    stream << "triclinic";
00170         if (symmetry_flag &SymmetryFlag::monoclinic)   stream << "monoclinic";
00171         if (symmetry_flag &SymmetryFlag::orthorhombic) stream << "orthorhombic";
00172         if (symmetry_flag &SymmetryFlag::tetragonal)   stream << "tetragonal";
00173         if (symmetry_flag &SymmetryFlag::trigonal)     stream << "trigonal";
00174         if (symmetry_flag &SymmetryFlag::hexagonal)    stream << "hexagonal";
00175         if (symmetry_flag &SymmetryFlag::cubic)        stream << "cubic";
00176         
00177         if (symmetry_flag &SymmetryFlag::k32)          stream << "k32";
00178         
00179         return symmetry_flag;
00180       }
00181     
00182     
00216     template <int dim, int rank, typename ValueType = double>
00217       class CrystalFieldBase
00218       :
00219       public Tensor<dim, rank, ValueType>
00220       {
00221         
00222       private:
00223       
00224       protected:
00225       
00229       Vector<ValueType> moduli_; 
00230       
00234       SymmetryFlag symmetry_flags_;
00235       
00239       SymmetryFlag group_flags_;
00240       
00241       
00246       virtual void assign_moduli (const Vector<ValueType> &moduli);
00247       
00248       public:
00249       
00253       CrystalFieldBase (const Vector<ValueType>     &moduli         = Vector<ValueType> (),
00254                         const SymmetryFlag          &symmetry_flags = SymmetryFlag::null,
00255                         const SymmetryFlag          &group_flags    = SymmetryFlag::null) 
00256       : 
00257       Tensor<dim, rank, ValueType> (),
00258       moduli_ (moduli),
00259       symmetry_flags_ (symmetry_flags),
00260       group_flags_ (group_flags)
00261       {}
00262       
00266       virtual ~CrystalFieldBase ();
00267       
00271       SymmetryFlag symmetry_flags () const; 
00272       
00276       SymmetryFlag group_flags () const; 
00277       
00282       virtual void assign_symmetry_flags (const SymmetryFlag &symmetry_flags,
00283                                           const SymmetryFlag &group_flags    = null);
00284       
00289       virtual void distribute_moduli (const Vector<ValueType> &moduli); 
00290       
00294       unsigned int n_components () const; 
00295       
00299       void write_gnuplot (std::ostream &out) const;
00300       
00305       CrystalFieldBase<dim, rank, ValueType> &operator = (const CrystalFieldBase<dim, rank, ValueType> &T);
00306       
00311       inline
00312       Tensor<dim, rank, ValueType> operator* () const
00313       {
00314         return (*this);
00315       }
00316       
00317       }; /* CrystalFieldBase */
00318     
00319     /*-------------- Inline and Other Functions -----------------------*/
00320     
00325     template <int dim, typename ValueType>
00326       inline
00327       Tensor<dim, 2, ValueType> 
00328       contract (const CrystalFieldBase<dim, 4, ValueType> &T_a,
00329                 const Tensor<dim, 2, ValueType>           &T_b) 
00330       {
00331         return contract (*T_a, T_b);
00332       } 
00333 
00334   } /* namespace Crystal */
00335 
00336 } /* namespace ewalena */
00337 
00338 #endif /* __ewalena_crystal_field_h */
00339 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines