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]); }