/* Fesslix - Stochastic Analysis
 * Copyright (C) 2010-2016 Wolfgang Betz
 *
 * Fesslix is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Fesslix is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Fesslix.  If not, see <http://www.gnu.org/licenses/>. 
 */

#ifndef fesslix_flxfem_element_planestr_H
#define fesslix_flxfem_element_planestr_H

#include "flxfem_elements.h"


/**
* @brief base class for 1D-elements
*/
class FLXFEM_EXPORT flxElement_2D_planestr : public flxElement_2D_base {
  protected:
    /**
    * @brief approx. polynomial degree of the term EA
    */
    const tuint degreeEt;
    const bool planestr;
    
    flxDOFfPtr DOFvec[2];
    
    /**
    * @brief some helping-variables
    */
    tdouble bovera;
    tdouble dxh_subel, dyh_subel;
    tdouble xm_subel, ym_subel;
    tuint Nx_N, Ny_N;		// number of shape functions for u_x and u_y
    tuint pom_x, pom_y;		// maximal polynomial order in x and y
    tuint edgeXorder[4];	// order of the edges for u_x
    tuint edgeYorder[4];	// order of the edges for u_y
    tuint bubbleXorderX;	// order of the u_x-bubbles in x
    tuint bubbleXorderY;	// order of the u_x-bubbles in y
    tuint bubbleYorderX;	// order of the u_y-bubbles in x
    tuint bubbleYorderY;	// order of the u_y-bubbles in y
    tuint subElX, subElY;	// index of the current sub-element
    bool tensorSpaceX;		// yes/no tensor-space of the u_x-bubbles
    bool tensorSpaceY;		// yes/no tensor-space of the u_y-bubbles
    bool edgeOrient[4];		// takes the orientation of the edge into account
    flxVec* Kel; tdouble* Kelp;
    flxVec* Kel_t; tdouble* Kelp_t;
    flxVec* rx; tdouble* rxp;
    flxVec* drx; tdouble* drxp;
    flxVec* ry; tdouble* ryp;
    flxVec* dry; tdouble* dryp;
    flxVec* dNxdx; tdouble* dNxdxp;
    flxVec* dNxdy; tdouble* dNxdyp;
    flxVec* dNydx; tdouble* dNydxp;
    flxVec* dNydy; tdouble* dNydyp;
    bool xyequal;
    
    virtual const tdouble get_el_info_help(const FlxElementInfo::elInfo eI) const;
    void assign_u_xy(const tuint i, const tuint j);
    void assembleStf_help(const tuint level, const_tuintPtr& vpos, tdoublePtr& ccpos, tuint GNx, tuint GNy, const tdouble xm, const tdouble ym, const tdouble dh);
    void update_GN(const tuint prev_level, tuint &GNx, tuint &GNy) const;
    void free_mem();
    /**
    * @brief 2D base of hierarchic Legendre polynomials (for this face)
    * @param res vector of size N_local_DOF
    */
    void dhLP_2D_base();
      void dhLP_2D_base_help(tdouble* res, const tdouble* r1, const tdouble* r2, const tuint* edgeorder, const tuint pOrderLx, const tuint pOrderLy, const bool tensSp);
      void hLP_2D_bemc(tdouble* res, const tdouble* r1p, const tdouble& r2p, const bool orient, const tuint edgeOrder) const;
      
    const bool check_hFEM(const tuint meshIntLx, const tuint meshIntLy);
  public:
    flxElement_2D_planestr(flxMaterial* material, flxFace& face, const bool planestr, FlxFunDeg* t);
    ~flxElement_2D_planestr();

    virtual void assembleStf(const tuint meshIntLx, const tuint meshIntLy, tuint **mesh, tdouble **mesh_cc, const tdouble* meshXLx, const tdouble* meshYLy,flxStiffnessMtxBase& stfmtx);
    virtual void assembleStfHfem(flxStiffnessMtxBase& stfmtx);
};



#endif // fesslix_flxfem_element_planestr_H