Home | Doxygen Documentation | Tutorials | Developer Tools (restricted)

app-bholger/gfem/unitcell.h
Go to the documentation of this file.
00001 #pragma once
00002 #include "hp2D/space.hh"
00003 #include "space/space.hh"
00004 #include "vector"
00005 #include "stdio.h"
00006 #include "function/vector.hh"
00007 #include "hp2D/hpAdaptiveSpaceH1.hh"
00008 #include "toolbox/sharedPointer.hh"
00009 
00010 namespace concepts {
00011 namespace gfem {
00012   using concepts::Real;
00013   using concepts::Cmplx;
00014 
00015 struct UC_Sol {
00016   typedef concepts::Vector<Cmplx> SolVec;
00017 
00018   UC_Sol(const concepts::Space<Real>& ucSpace, Cmplx k1=Cmplx(0,0), Cmplx k2=Cmplx(0,0))
00019     : vec(ucSpace)
00020     , sigma(0)
00021   {
00022     k[0] = k1;
00023     k[1] = k2;
00024   }
00025 
00026   UC_Sol(const SolVec& vec, Cmplx k1, Cmplx k2)
00027     : vec(vec)
00028     , sigma(0)
00029   { 
00030     k[0] = k1;
00031     k[1] = k2;
00032   }
00033 
00034   bool operator<(const UC_Sol& other) const {
00035     return sigma < other.sigma;
00036   }
00037 
00038   void print() const {
00039     printf("UC_Sol(%7.2f  %+7.2fi, %7.2f  %+7.2fi)\n"
00040         , real(k[0])
00041         , imag(k[0])
00042         , real(k[1])
00043         , imag(k[1])
00044         );
00045   }
00046   
00047 
00048   SolVec vec; // periodic coefficients of solution
00049   Cmplx k[2]; // k vector for quasi-periodic boundary conditions
00050   double sigma; // singular value, used in GfemBasisOne
00051 };
00052 
00053 struct GfemCellParams {
00055   static const int SEL_PER = -100; // only special mic osc (1) selected
00056   static const int SEL_ALL = 0;
00057   static const int SEL_NEG = -1;
00058   static const int SEL_POS = 1;
00059 
00060   GfemCellParams(int p_macro=0, int selX=SEL_ALL, int selY = SEL_ALL) {
00061     p_macros[0] = p_macro;
00062     p_macros[1] = p_macro;
00063 
00064     #if 0
00065     dir_sel[0] = SEL_ALL;
00066     dir_sel[1] = SEL_POS; // FIXME: this hardcodes infBarrier geometry
00067     //dir_sel[1] = SEL_ALL;
00068     #endif
00069     
00070     dir_sel[0] = selX;
00071     dir_sel[1] = selY;
00072 
00073   }
00074 
00075   int p_macros[2];
00076 
00077   int dir_sel[2];
00078 };
00079 
00080 
00084 struct Unitcell {
00085   Unitcell(RCP<const hp2D::hpAdaptiveSpaceH1> ucSpace);
00086 
00088   void addSolution(UC_Sol* sol) {
00089     uc_sols.push_back(sol);
00090   }
00091 
00092   const UC_Sol& getSolution(int i) const {
00093     return *(uc_sols[i]);
00094   }
00095   
00096   UC_Sol& getSolution(int i) {
00097     return *(uc_sols[i]);
00098   }
00099 
00100   int size() const {
00101     return (int)uc_sols.size();
00102   }
00103 
00104 
00105   ~Unitcell() {
00106     clear();
00107   }
00108 
00109   void clear() {
00110     if(!shallow) {
00111       for(int i=0; i < (int)uc_sols.size(); ++i)
00112         delete uc_sols[i];
00113     }
00114     uc_sols.clear();
00115   }
00116 
00117   Unitcell(const Unitcell& other, bool shallow = false)
00118     : ucSpace(other.ucSpace)
00119     , offX(other.offX)
00120     , offY(other.offY)
00121     , sizeX(other.sizeX)
00122     , sizeY(other.sizeY)
00123     , shallow(shallow)
00124   {
00125     if(!shallow) {
00126       // deep copy
00127       for(int i=0; i < (int)other.uc_sols.size(); ++i)
00128         uc_sols.push_back(new UC_Sol(*other.uc_sols[i]));
00129     } else {
00130       // shallow copy
00131       for(int i=0; i < (int)other.uc_sols.size(); ++i)
00132         uc_sols.push_back( other.uc_sols[i] );
00133     }
00134   }
00135 private:
00136   Unitcell& operator=(const Unitcell& other);
00137 
00138 public:
00139 
00140   RCP<const hp2D::hpAdaptiveSpaceH1> ucSpace;
00141   Real offX;
00142   Real offY;
00143   Real sizeX;
00144   Real sizeY;
00145 
00146 private:
00147   std::vector< UC_Sol* > uc_sols;
00148   bool shallow;
00149 };
00150 
00151 struct UnitcellMask : public Unitcell {
00152   static const int UC_ACTIVE = 1;
00153   static const int UC_INACTIVE = 0;
00154 
00155   UnitcellMask(const Unitcell& other)
00156    : Unitcell(other, true)
00157    , uc_active(other.size(), UC_ACTIVE)
00158   {
00159     assert(size() == other.size());
00160     assert(sizeActive() == other.size());
00161     //new(*this) (other, false);
00162   }
00163 
00164   ~UnitcellMask() {
00165     uc_active.clear();
00166   }
00167 
00168 private:
00169   UnitcellMask(const UnitcellMask& other);
00170   UnitcellMask& operator=(const UnitcellMask& other);
00171 
00172 public:
00173   static bool isActive(Cmplx k, int sel_mode) {
00174     if(sel_mode == GfemCellParams::SEL_ALL)
00175       return true;
00176 
00177     if(sel_mode == GfemCellParams::SEL_POS)
00178       return imag(k) >= 0;
00179     
00180     if(sel_mode == GfemCellParams::SEL_NEG)
00181       return imag(k) <= 0;
00182 
00183     if(sel_mode == GfemCellParams::SEL_PER)
00184       return imag(k) == 0 && real(k) == 0;
00185 
00186     if(sel_mode == GfemCellParams::SEL_ALL)
00187       return true;
00188 
00189     assert(false);
00190   }
00191 
00193   void updateActive(int i_sol, const GfemCellParams* cell_p) {
00194     setActive(i_sol, isActive(getSolution(i_sol), cell_p) );
00195   }
00196 
00197   void checkDeactivateAll(const GfemCellParams* cell_p) {
00198     for(int i=0; i < size(); ++i)
00199       checkDeactivate(i, cell_p);
00200   }
00201 
00203   void checkDeactivate(int i_sol, const GfemCellParams* cell_p) {
00204     if(!isActive(getSolution(i_sol), cell_p))
00205       setActive(i_sol, false );
00206   }
00207 
00208   static bool isActive(const UC_Sol& sol, const GfemCellParams* cell_p) {
00209     return isActive(sol.k[0], cell_p->dir_sel[0])
00210           && isActive(sol.k[1], cell_p->dir_sel[1]);
00211   }
00212 
00213 #if 0
00214   const UC_Sol& getSolution(int i_sel, const GfemCellParams* cell_p) const {
00215     if(cell_p == NULL)
00216       return getSolution(i_sel);
00217 
00218     for(int i=0; i < size(); ++i) {
00219       const UC_Sol& sol = getSolution(i);
00220 
00221       if(isActive(sol, cell_p))
00222       {
00223         if(i_sel == 0)
00224           return sol;
00225         --i_sel;
00226       } 
00227     }
00228     assert(false);
00229   }
00230 
00231 
00232   int size(const GfemCellParams* cell_p) const {
00233     if(cell_p == NULL)
00234       return size();
00235 
00236     int active = 0;
00237     for(int i=0; i < size(); ++i) {
00238       const UC_Sol& sol = getSolution(i);
00239 
00240       if(isActive(sol, cell_p)) {
00241         active++;
00242       } else {
00243         printf("disabling ");
00244         sol.print();
00245       } 
00246     }
00247     return active;
00248   }
00249 #endif
00250   bool isActive(int i_sol) const {
00251     return uc_active[i_sol] == UC_ACTIVE;
00252   }
00253 
00254   void setActive(int i_sol, bool state) {
00255     uc_active[i_sol] = state;
00256   }
00257 
00258   int sizeActive() const {
00259     assert(int(uc_active.size()) == size());
00260 
00261     int res = 0;
00262     for(int i=0; i < size(); ++i) {
00263       if(isActive(i))
00264         res++;
00265     }
00266     return res;
00267   }
00268 
00269 private:
00270   std::vector< int > uc_active;
00271 };
00272 
00273 } // namespace
00274 } // namespace

Home | Doxygen Documentation | Tutorials | Developer Tools (restricted)