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
00073
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
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:
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
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
00308
00309
00310 getUCBF_LapType(0, 0, 0) = ucBF_id;
00311 getUCBF_LapType(0, 0, 1) = ucBF_id;
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;
00355
00356 std::vector<Cmplx*> ucBF_ids;
00357 std::vector<Cmplx**> ucBF_laps;
00358 };
00359
00360 }
00361 }