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

app-bholger/gfem/gfemUCQuad.h
Go to the documentation of this file.
00001 #pragma once
00002 
00003 #include <iostream>
00004 #include <memory>
00005 #include "basics/typedefs.hh"
00006 #include "basics/vectorsMatrices.hh"
00007 #include "toolbox/sharedPointer.hh"
00008 #include "formula/formula.hh"
00009 #include "formula/elementFormulaRCP.hh"
00010 #include "geometry/cell2D.hh"
00011 #include "geometry/integral.hh"
00012 #include "integration/quadRule.hh"
00013 #include "integration/karniadakis.hh"
00014 #include "space/integral.hh"
00015 #include "space/element.hh"
00016 #include "function/vector.hh"
00017 #include "hp2D/quad.hh"
00018 #include "unitcell.h"
00019 #include "gfemOverlapCondition.h"
00020 #include "gfemDofIterator.h"
00021 #include "karniadakis.h"
00022 
00023 namespace concepts {
00024 namespace gfem {
00025 
00026 
00027 class GfemUCQuad {
00028 public:
00029   GfemUCQuad(const Unitcell& uc, int p_macro[2]
00030       ); 
00031   virtual ~GfemUCQuad();
00032 
00033 private:
00034   GfemUCQuad(const GfemUCQuad& other);
00035   GfemUCQuad& operator=(const GfemUCQuad& other);
00036 
00037 public:
00038   void recomputeShapefunctions() {
00039     clear();
00040     initialise();
00041 
00042     std::vector< RCP<const ElementFormula<Cmplx> > > formulasOld(formulas);
00043     std::vector< EvalMode > modesOld(modes);
00044     formulas.clear();
00045     modes.clear();
00046 
00047     for(uint i=0; i < formulas.size(); ++i) {
00048       addFormula(formulasOld[i], modes[i]);
00049     }
00050   }
00051   
00052   int getFomulaId(const ElementFormula<Cmplx>* formula_adr) 
00053   {
00054     for(size_t i=0; i < formulas.size(); ++i) {
00055       if(formulas[i].get() == formula_adr)
00056         return i;
00057     }
00058     return -1;
00059   }
00060 
00061   void unsetCurFomula() {
00062     ucBF_lap = NULL;
00063     ucBF_id = NULL;
00064   }
00065 
00066   void setCurFomula(int id) {
00067     assert(id < (int)formulas.size());
00068 
00069     ucBF_id = ucBF_ids[id];
00070     ucBF_lap = ucBF_laps[id];
00071     cur_mode = modes[id];
00072     /*for(int i=0; i < N_LAP_COMP; ++i) { 
00073       ucBF_lap[i] = ucBF_laps[id][i];
00074     }*/
00075   }
00076   
00078   void activateFormula(const concepts::ElementFormula<Cmplx>* formula) {
00079     int id = getFomulaId(formula);
00080     if(id < 0) {
00081       std::cout << *formula << std::endl; 
00082       CONCEPTS_SIMPLE_EXC("formula not initialised ");
00083     }
00084     setCurFomula(id);
00085   }
00086 
00087   enum EvalMode { EVAL_ON_MICRO = 0, EVAL_ON_MACRO };
00088 
00090   void registerFormula(const RCP<const concepts::ElementFormula<Cmplx> >& formula, 
00091                        EvalMode mode = EVAL_ON_MICRO) 
00092   {
00093     int id = getFomulaId(formula.get());
00094     if(id == -1) {
00095       addFormula(formula, mode);
00096 
00097       //assert(getFomulaId(formula.get()) >= 0);
00098     } else {
00099       setCurFomula(id);
00100     }
00101   }
00102 
00103   int numMacro() const {
00104     return numMacroX() * numMacroY();
00105   }
00106 
00107   int numMacroX() const {
00108     return n_shape_macro_x;
00109   }
00110 
00111   int numMacroY() const {
00112     return n_shape_macro_y;
00113   }
00114 
00115   int numMicro() const {
00116     return n_micro;
00117   }
00118 
00119   int numUCFun() const {
00120     return n_ucfun;
00121   }
00122 
00123   const Unitcell& getUC() const {
00124     return uc;
00125   }
00126 
00127   const Cmplx* getQPpart(int iMic) const {
00128     return uc.getSolution(iMic).k;
00129   }
00130 
00132   int num_shape() const {
00133     return numLDof();
00134   }
00135 
00140   const int* getPMax() {
00141     return p_max;
00142   }
00143 
00147   const int* getPMacro() {
00148     return p_macro;
00149   }
00150 
00151   int numLDof() const {
00152     return begin().numLdofs();
00153   }
00154 
00155   const GfemDofIterator& begin() const {
00156     return it_begin;
00157   }
00158 
00159 public: // access quadrature helper functions
00160   int numQuadPoints() const {
00161     return nquad;
00162   }
00163 
00164   Real2d getUCPoint(int i_quad, int repx=0, int repy=0) const  {
00165     assert(i_quad < numQuadPoints());
00166     return Real2d( ((abscissas_x[i_quad]+1)/2 + uc.offX + repx) * uc.sizeX 
00167         ,          ((abscissas_y[i_quad]+1)/2 + uc.offY + repy) * uc.sizeY );
00168   }
00169 
00170   const ElementWithCell<Real>* getMicroElem(int i_quad) const {
00171     return micro_elems[i_quad];
00172   }
00173 
00174   MapReal2d getMicroJacobian(int i_quad) const {
00175     // TODO: check if we want it this way
00176     return (uc_jacobian[i_quad] * 2);
00177   }
00178 
00179     const Cmplx& getMicroShape(int i_micro, int i_quad) const {
00180       return const_cast<GfemUCQuad*>(this)->getMicroShape(i_micro, i_quad);
00181     }
00182     
00183     Real getMacroShape(int i_macro, Real x) const 
00184     {
00185       KarniadakisCoeffs& kcoeffs = KarniadakisCoeffs::getInstance();
00186       const PolyCoeff& p = kcoeffs.getCoeffs(i_macro); 
00187       return p.eval(x);
00188     }
00189 
00190     Real2d getMacroShapeD_unit(int i_macro1, int i_macro2, Real x, Real y) const 
00191     {
00192       KarniadakisCoeffs& kcoeffs = KarniadakisCoeffs::getInstance();
00193       const PolyCoeff& px   = kcoeffs.getCoeffs (i_macro1); 
00194       const PolyCoeff& py   = kcoeffs.getCoeffs (i_macro2); 
00195       const PolyCoeff& px_D = kcoeffs.getCoeffsD(i_macro1); 
00196       const PolyCoeff& py_D = kcoeffs.getCoeffsD(i_macro2); 
00197  
00198       const Real res_x = px_D.eval(x) * py  .eval(y);
00199       const Real res_y = px  .eval(x) * py_D.eval(y);
00200 
00201       return Real2d(res_x, res_y);
00202     }
00203 
00204     Real powi(Real x, int power) {
00205       Real res(1);
00206       for(int i = 0; i < power; ++i) {
00207         res *= x;
00208       }
00209       return res;
00210     }
00211 
00212     Cmplx& getMicroShape(int i_ucfun, int i_quad) {
00213       assert(i_quad < nquad);
00214       assert(i_ucfun < numMicro());
00215       return uc_shape[i_ucfun * nquad + i_quad];
00216     }
00217 
00218     const Cmplx2d& getMicroShapeD(int i_ucfun, int i_quad) const {
00219       return const_cast<GfemUCQuad*>(this)->getMicroShapeD(i_ucfun, i_quad);
00220     }
00221 
00222     Cmplx2d& getMicroShapeD(int i_ucfun, int i_quad) 
00223     {
00224       assert(i_quad < nquad);
00225       assert(i_ucfun < numMicro());
00226       return uc_shape_D[i_ucfun * nquad + i_quad];
00227     }
00228 
00229     const Real& getWeight(int i_quad) const  {
00230       return weights[i_quad];
00231     }
00232 
00233     int numMonomX() {
00234       return 2*getPMax()[0]+1;
00235     }
00236 
00237     int numMonomY() {
00238       return 2*getPMax()[1]+1;
00239     }
00240 
00248     Cmplx getUCBF_Id(int px, int py, int iMicro1, int iMicro2) const {
00249       return const_cast<GfemUCQuad*>(this)->getUCBF_Id(px, py, iMicro1, iMicro2);
00250     }
00251 
00252     Cmplx& getUCBF_Id(int px, int py, int iMicro1, int iMicro2) {
00253       return getUCBF(ucBF_id, px, py, iMicro1, iMicro2);
00254     }
00264     Cmplx getUCBF_Lap(int px, int py, int iMicro1, int iMicro2,
00265         int i_diff1, int i_diff2, int i_comp) const 
00266     { 
00267       return const_cast<GfemUCQuad*>(this)->getUCBF_Lap(px, py, iMicro1, iMicro2,
00268           i_diff1, i_diff2, i_comp);
00269     }
00270 
00271     Cmplx& getUCBF_Lap(int px, int py, int iMicro1, int iMicro2, 
00272         int i_diff1, int i_diff2, int i_comp) 
00273     {
00274       Cmplx* arr = getUCBF_LapType(i_diff1, i_diff2, i_comp);
00275       return getUCBF(arr, px, py, iMicro1, iMicro2);
00276     }
00279 protected:
00280     void initialise();
00281     void clear();
00282     void fillUCBF(const concepts::ElementFormula<Cmplx>& formula);
00283 
00284     Cmplx& getUCBF(Cmplx* vals,  int px, int py, int iMicro1, int iMicro2) {
00285       const int mul1 = numMicro();
00286       const int mul2 = mul1 * numMicro();
00287       const int mul3 = mul2 * numMonomX();
00288 
00289       return vals[iMicro1 + iMicro2*mul1 + px*mul2 + py*mul3];
00290     }
00291 
00292     Cmplx*& getUCBF_LapType(int i_diff1, int i_diff2, int i_comp) {
00293       const int idxType = i_diff1*4 + i_diff2*2 + i_comp;
00294 
00295       return ucBF_lap[idxType];
00296     }
00297 
00298     void addFormula(const RCP<const concepts::ElementFormula<Cmplx> >& formula,
00299                     EvalMode mode) 
00300     {
00301       formulas.push_back(formula);
00302       modes.push_back(mode);
00303       ucBF_ids.push_back(new Cmplx[n_ucBF]);
00304       ucBF_laps.push_back(new Cmplx*[8]);
00305 
00306       setCurFomula(formulas.size()-1);
00307       //ucBF_id = ucBF_ids.back();
00308       //ucBF_laps = ucBF_laps.back();
00309 
00310       getUCBF_LapType(0, 0, 0) = ucBF_id; // all derivatives are on macro functions 
00311       getUCBF_LapType(0, 0, 1) = ucBF_id; // all derivatives are on macro functions
00312       getUCBF_LapType(0, 1, 0) = new Cmplx[n_ucBF];
00313       getUCBF_LapType(0, 1, 1) = new Cmplx[n_ucBF];
00314       getUCBF_LapType(1, 0, 0) = new Cmplx[n_ucBF];
00315       getUCBF_LapType(1, 0, 1) = new Cmplx[n_ucBF];
00316       getUCBF_LapType(1, 1, 0) = new Cmplx[n_ucBF];
00317       getUCBF_LapType(1, 1, 1) = new Cmplx[n_ucBF];
00318 
00319       fillUCBF(*formula);
00320     }
00321 
00322 
00323 private:
00324     const Unitcell& uc;
00325 
00326     GfemOverlapCondition overC;
00327     GfemDofIterator it_begin;
00328 
00329     std::vector< RCP<const ElementFormula<Cmplx> > > formulas;
00330     std::vector< EvalMode > modes;
00331 
00332     int p_max[2];
00333     int p_macro[2];
00334     int n_micro;
00335     int n_ucfun; 
00336     int n_ucBF;
00337     EvalMode cur_mode;
00338 
00339     int nquad;
00340     int n_shape_macro_x;
00341     int n_shape_macro_y;
00342 
00343     Real* abscissas_x;
00344     Real* abscissas_y;
00345     Real* weights;
00346     MapReal2d* uc_jacobian;
00347     const ElementWithCell<Real>** micro_elems;
00348 
00349     Cmplx* uc_shape;
00350     Cmplx2d* uc_shape_D;
00351 
00352     static const int N_LAP_COMP = 8;
00353     Cmplx* ucBF_id;
00354     Cmplx** ucBF_lap; // Cmplx*[N_LAP_COMP]
00355 
00356     std::vector<Cmplx*> ucBF_ids;
00357     std::vector<Cmplx**> ucBF_laps; // Cmplx*[N_LAP_COMP]
00358 };
00359 
00360 } // namespace
00361 } // namespace

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