20#ifndef __B2ELEMENT_KLT_UTIL_H__ 
   21#define __B2ELEMENT_KLT_UTIL_H__ 
   28#include "b2ppconfig.h" 
   29#include "utils/b2linear_algebra.H" 
   58    GEOM_ANALYTIC_CYLINDER,
 
   59    GEOM_ANALYTIC_HYPERBOLIC_PARABOLOID,
 
   60    GEOM_ANALYTIC_STRAIGHT_EDGES
 
   63class IntegrationScheme {
 
   65    size_t get_num()
 const { 
return int(points.size()); }
 
   67    void get_point(
const size_t ip, 
double xi[2], 
double& weight)
 const {
 
   68        const Point& p = points[ip];
 
   69        std::copy(p.xi, p.xi + 2, xi);
 
   77        Point(
const double xi_[2], 
const double weight_) : weight(weight_) {
 
   78            std::copy(xi_, xi_ + 2, xi);
 
   81        Point(
const double r, 
const double s, 
const double weight_) : weight(weight_) {
 
   87    typedef std::vector<Point> PointVector;
 
   95    Array2() : size1_(0), size2_(0), m2_(0), m3_(0) {}
 
   97    Array2(
size_t size1, 
size_t size2, 
const T& t = T())
 
   98        : size1_(size1), size2_(size2), m2_(size1_), m3_(m2_ * size2_), data_(m3_, t) {}
 
  100    void set_zero() { std::fill(data_.begin(), data_.end(), T()); }
 
  102    void swap(Array2& o) {
 
  103        std::swap(size1_, o.size1_);
 
  104        std::swap(size2_, o.size2_);
 
  105        std::swap(m2_, o.m2_);
 
  106        std::swap(m3_, o.m3_);
 
  110    template <
typename T1>
 
  111    Array2& operator=(
const Array2<T1>& o) {
 
  117        for (
size_t i = 0; i != m3_; ++i) { data_[i] = o.data_[i]; }
 
  121    Array2& operator=(
const Array2& o) {
 
  130    size_t size1()
 const { 
return size1_; }
 
  132    size_t size2()
 const { 
return size2_; }
 
  134    size_t msize1()
 const { 
return 1; }
 
  136    size_t msize2()
 const { 
return m2_; }
 
  138    size_t msize3()
 const { 
return m3_; }
 
  140    size_t esize()
 const { 
return m3_; }
 
  142    void resize(
size_t size1, 
size_t size2, 
const T& t = T()) {
 
  147        data_.resize(m3_, t);
 
  150    size_t index(
size_t i1, 
size_t i2)
 const { 
return i1 * m2_ + i2; }
 
  152    const T& operator()(
size_t i1, 
size_t i2)
 const { 
return data_[index(i1, i2)]; }
 
  154    T& operator()(
size_t i1, 
size_t i2) { 
return data_[index(i1, i2)]; }
 
  156    const T& operator[](
size_t i)
 const { 
return data_[i]; }
 
  158    T& operator[](
size_t i) { 
return data_[i]; }
 
  165    std::vector<T> data_;
 
  173    std::vector<double> d1;  
 
  176    DofScalar() : ndof(0), first(false), second(false), d0(0.) {}
 
  178    DofScalar(
const size_t ndof_, 
const bool first_, 
const bool second_)
 
  183          d1((first ? ndof : 0), 0.),
 
  184          d2((second ? ndof : 0), (second ? ndof : 0), 0.) {}
 
  186    void resize(
const size_t ndof_, 
const bool first_, 
const bool second_) {
 
  189        d1.resize((first ? ndof_ : 0), 0.);
 
  190        d2.resize((second ? ndof_ : 0), (second ? ndof_ : 0), 0.);
 
  194    size_t size()
 const { 
return ndof; }
 
  196    DofScalar& set_zero() {
 
  198        if (first) { std::fill(d1.begin(), d1.end(), 0); }
 
  199        if (second) { d2.set_zero(); }
 
  203    DofScalar& operator*=(
const double o) {
 
  205        for (
size_t i = 0; i != d1.size(); ++i) { d1[i] *= o; }
 
  206        for (
size_t i = 0; i != d2.esize(); ++i) { d2[i] *= o; }
 
  210    DofScalar& operator+=(
const DofScalar& o) {
 
  211        assert(size() == o.size());
 
  213        if (first && o.first) {
 
  214            assert(d1.size() == o.d1.size());
 
  215            for (
size_t i = 0; i != d1.size(); ++i) { d1[i] += o.d1[i]; }
 
  217        if (second && o.second) {
 
  218            assert(d2.esize() == o.d2.esize());
 
  219            for (
size_t i = 0; i != d2.esize(); ++i) { d2[i] += o.d2[i]; }
 
  224    DofScalar& assign(
const DofScalar& o) {
 
  225        assert(ndof == o.ndof);
 
  227        if (first && o.first) {
 
  228            assert(d1.size() == o.d1.size());
 
  229            for (
size_t i = 0; i != d1.size(); ++i) { d1[i] = o.d1[i]; }
 
  231            std::fill(d1.begin(), d1.end(), 0);
 
  233        if (second && o.second) {
 
  234            assert(d2.esize() == o.d2.esize());
 
  235            for (
size_t i = 0; i != d2.esize(); ++i) { d2[i] = o.d2[i]; }
 
  242    DofScalar& muladd(
const DofScalar& o, 
const double f) {
 
  243        assert(ndof == o.ndof);
 
  245        if (first && o.first) {
 
  246            assert(d1.size() == o.d1.size());
 
  247            for (
size_t i = 0; i != d1.size(); ++i) { d1[i] += f * o.d1[i]; }
 
  249        if (second && o.second) {
 
  250            assert(d2.esize() == o.d2.esize());
 
  251            for (
size_t i = 0; i != d2.esize(); ++i) { d2[i] += f * o.d2[i]; }
 
  256    DofScalar& add_at_offset(
const size_t offset, 
const DofScalar& o) {
 
  257        if (ndof < offset + o.ndof) { resize(offset + o.ndof, first, second); }
 
  259        for (
size_t k = 0; k != o.ndof; ++k) { d1[offset + k] = o.d1[k]; }
 
  260        for (
size_t k = 0; k != o.ndof; ++k) {
 
  261            for (
size_t l = 0; l <= k; ++l) { d2(offset + k, offset + l) = o.d2(k, l); }
 
  276    DofVector(
const size_t ndof, 
const bool first, 
const bool second) {
 
  277        resize(ndof, first, second);
 
  280    void resize(
const size_t ndof, 
const bool first, 
const bool second) {
 
  281        for (
int j = 0; j != NUMD; ++j) { e[j].resize(ndof, first, second); }
 
  284    size_t size()
 const { 
return e[0].size(); }
 
  286    DofVector& set_zero() {
 
  287        for (
int j = 0; j != NUMD; ++j) { e[j].set_zero(); }
 
  291    const DofScalar& operator[](
const size_t i)
 const { 
return e[i]; }
 
  293    DofScalar& operator[](
const size_t i) { 
return e[i]; }
 
  295    DofVector& operator*=(
const double o) {
 
  296        for (
int j = 0; j != NUMD; ++j) { e[j] *= o; }
 
  300    DofVector& operator+=(
const DofVector& o) {
 
  301        for (
int j = 0; j != NUMD; ++j) { e[j] += o[j]; }
 
  305    DofVector& add_at_offset(
const size_t offset, 
const DofVector& o) {
 
  306        for (
int j = 0; j != NUMD; ++j) { e[j].add_at_offset(offset, o[j]); }
 
  319    DofMatrix(
const size_t ndof, 
const bool first, 
const bool second) {
 
  320        resize(ndof, first, second);
 
  323    void resize(
const size_t ndof, 
const bool first, 
const bool second) {
 
  324        for (
int j = 0; j != 3; ++j) { e[j].resize(ndof, first, second); }
 
  327    size_t size()
 const { 
return e[0].size(); }
 
  329    DofMatrix& set_zero() {
 
  330        for (
int j = 0; j != 3; ++j) { e[j].set_zero(); }
 
  334    const DofVector<3>& operator[](
const size_t i)
 const { 
return e[i]; }
 
  336    DofVector<3>& operator[](
const size_t i) { 
return e[i]; }
 
  338    DofMatrix& operator*=(
const double o) {
 
  339        for (
int j = 0; j != 3; ++j) { e[j] *= o; }
 
  343    DofMatrix& operator+=(
const DofMatrix& o) {
 
  344        for (
int j = 0; j != 3; ++j) { e[j] += o[j]; }
 
  348    DofMatrix& add_at_offset(
const size_t offset, 
const DofMatrix& o) {
 
  349        for (
int j = 0; j != 3; ++j) { e[j].add_at_offset(offset, o[j]); }
 
  376    ScalarXiDof(
const size_t ndof, 
const bool first, 
const bool second) {
 
  377        resize(ndof, first, second);
 
  380    void resize(
const size_t ndof, 
const bool first, 
const bool second) {
 
  381        for (
int i = 0; i != NUMD; ++i) { e[i].resize(ndof, first, second); }
 
  384    size_t size()
 const { 
return e[0].size(); }
 
  386    ScalarXiDof& set_zero() {
 
  387        for (
int i = 0; i != NUMD; ++i) { e[i].set_zero(); }
 
  391    const DofScalar& operator[](
const size_t i)
 const {
 
  396    DofScalar& operator[](
const size_t i) {
 
  401    ScalarXiDof& operator*=(
const double o) {
 
  402        for (
int i = 0; i != NUMD; ++i) { e[i] *= o; }
 
  406    ScalarXiDof& operator+=(
const ScalarXiDof& o) {
 
  407        for (
int i = 0; i != NUMD; ++i) { e[i] += o[i]; }
 
  411    ScalarXiDof& muladd(
const ScalarXiDof& o, 
const double f) {
 
  412        for (
int i = 0; i != NUMD; ++i) { e[i].muladd(o[i], f); }
 
  416    ScalarXiDof& add_at_offset(
const size_t offset, 
const ScalarXiDof& o) {
 
  417        for (
int i = 0; i != NUMD; ++i) { e[i].add_at_offset(offset, o[i]); }
 
  428    ScalarXiDof<NUMD> e[3];
 
  432    VectorXiDof(
const size_t ndof, 
const bool first, 
const bool second) {
 
  433        resize(ndof, first, second);
 
  436    void resize(
const size_t ndof, 
const bool first, 
const bool second) {
 
  437        for (
int j = 0; j != 3; ++j) { e[j].resize(ndof, first, second); }
 
  440    size_t size()
 const { 
return e[0].size(); }
 
  442    VectorXiDof& set_zero() {
 
  443        for (
int j = 0; j != 3; ++j) { e[j].set_zero(); }
 
  447    const ScalarXiDof<NUMD>& operator[](
const size_t i)
 const {
 
  452    ScalarXiDof<NUMD>& operator[](
const size_t i) {
 
  457    VectorXiDof& operator*=(
const double o) {
 
  458        for (
int j = 0; j != 3; ++j) { e[j] *= o; }
 
  462    VectorXiDof& operator+=(
const VectorXiDof& o) {
 
  463        for (
int j = 0; j != 3; ++j) { e[j] += o[j]; }
 
  467    VectorXiDof& add_at_offset(
const size_t offset, 
const VectorXiDof& o) {
 
  468        for (
int j = 0; j != 3; ++j) { e[j].add_at_offset(offset, o[j]); }
 
  480    VectorXiDof<NUMD> e[3];
 
  484    MatrixXiDof(
const size_t ndof, 
const bool first, 
const bool second) {
 
  485        resize(ndof, first, second);
 
  488    void resize(
const size_t ndof, 
const bool first, 
const bool second) {
 
  489        for (
int j = 0; j != 3; ++j) { e[j].resize(ndof, first, second); }
 
  492    size_t size()
 const { 
return e[0].size(); }
 
  494    MatrixXiDof& set_zero() {
 
  495        for (
int j = 0; j != 3; ++j) { e[j].set_zero(); }
 
  499    const VectorXiDof<NUMD>& operator[](
const size_t i)
 const { 
return e[i]; }
 
  501    VectorXiDof<NUMD>& operator[](
const size_t i) { 
return e[i]; }
 
  503    MatrixXiDof& operator*=(
const double o) {
 
  504        for (
int j = 0; j != 3; ++j) { e[j] *= o; }
 
  508    MatrixXiDof& operator+=(
const MatrixXiDof& o) {
 
  509        for (
int j = 0; j != 3; ++j) { e[j] += o[j]; }
 
  513    MatrixXiDof& add_at_offset(
const size_t offset, 
const MatrixXiDof& o) {
 
  514        for (
int j = 0; j != 3; ++j) { e[j].add_at_offset(offset, o[j]); }
 
  519typedef Vec3<double> Vec3d;
 
  529    std::vector<Vec3d> d1;  
 
  532    DofVec3d() : ndof(0), first(false), second(false) {}
 
  534    DofVec3d(
const size_t ndof_, 
const bool first_, 
const bool second_)
 
  538          d1((first ? ndof : 0), Vec3d()),
 
  539          d2((second ? ndof : 0), (second ? ndof : 0), Vec3d()) {}
 
  541    void resize(
const size_t ndof_, 
const bool first_, 
const bool second_) {
 
  544        d1.resize((first ? ndof_ : 0), Vec3d());
 
  545        d2.resize((second ? ndof_ : 0), (second ? ndof_ : 0), Vec3d());
 
  549    size_t size()
 const { 
return ndof; }
 
  551    DofVec3d& set_zero() {
 
  553        if (first) { std::fill(d1.begin(), d1.end(), Vec3d()); }
 
  554        if (second) { d2.set_zero(); }
 
  558    DofVec3d& operator*=(
const double o) {
 
  560        for (
size_t i = 0; i != d1.size(); ++i) { d1[i] *= o; }
 
  561        for (
size_t i = 0; i != d2.esize(); ++i) { d2[i] *= o; }
 
  565    DofVec3d& operator+=(
const DofVec3d& o) {
 
  566        assert(size() == o.size());
 
  568        if (first && o.first) {
 
  569            assert(d1.size() == o.d1.size());
 
  570            for (
size_t i = 0; i != d1.size(); ++i) { d1[i] += o.d1[i]; }
 
  572        if (second && o.second) {
 
  573            assert(d2.esize() == o.d2.esize());
 
  574            for (
size_t i = 0; i != d2.esize(); ++i) { d2[i] += o.d2[i]; }
 
  579    DofVec3d& assign(
const DofVec3d& o) {
 
  580        assert(ndof == o.ndof);
 
  582        if (first && o.first) {
 
  583            assert(d1.size() == o.d1.size());
 
  584            for (
size_t i = 0; i != d1.size(); ++i) { d1[i] = o.d1[i]; }
 
  586            for (
size_t i = 0; i != d1.size(); ++i) { d1[i].set_zero(); }
 
  588        if (second && o.second) {
 
  589            assert(d2.esize() == o.d2.esize());
 
  590            for (
size_t i = 0; i != d2.esize(); ++i) { d2[i] = o.d2[i]; }
 
  597    DofVec3d& muladd(
const DofVec3d& o, 
const double f) {
 
  598        assert(ndof == o.ndof);
 
  600        if (first && o.first) {
 
  601            assert(d1.size() == o.d1.size());
 
  602            for (
size_t i = 0; i != d1.size(); ++i) { d1[i] += f * o.d1[i]; }
 
  604        if (second && o.second) {
 
  605            assert(d2.esize() == o.d2.esize());
 
  606            for (
size_t i = 0; i != d2.esize(); ++i) { d2[i] += f * o.d2[i]; }
 
  622    XiDofVec3d(
const size_t ndof, 
const bool first, 
const bool second) {
 
  623        resize(ndof, first, second);
 
  626    void resize(
const size_t ndof, 
const bool first, 
const bool second) {
 
  627        for (
int i = 0; i != NUMD; ++i) { e[i].resize(ndof, first, second); }
 
  630    size_t size()
 const { 
return e[0].size(); }
 
  632    XiDofVec3d& set_zero() {
 
  633        for (
int i = 0; i != NUMD; ++i) { e[i].set_zero(); }
 
  637    const DofVec3d& operator[](
const size_t i)
 const {
 
  642    DofVec3d& operator[](
const size_t i) {
 
  647    XiDofVec3d& operator*=(
const double o) {
 
  648        for (
int i = 0; i != NUMD; ++i) { e[i] *= o; }
 
  652    XiDofVec3d& operator+=(
const XiDofVec3d& o) {
 
  653        for (
int i = 0; i != NUMD; ++i) { e[i] += o[i]; }
 
  657    XiDofVec3d& muladd(
const XiDofVec3d& o, 
const double f) {
 
  658        for (
int i = 0; i != NUMD; ++i) { e[i].muladd(o[i], f); }
 
  662    XiDofVec3d& add_at_offset(
const size_t offset, 
const XiDofVec3d& o) {
 
  663        for (
int i = 0; i != NUMD; ++i) { e[i].add_at_offset(offset, o[i]); }