20#ifndef B2BEAM_CROSS_SECTION_SOLVER_H_
21#define B2BEAM_CROSS_SECTION_SOLVER_H_
25#include "b2blaslapack.H"
26#include "b2ppconfig.h"
27#include "elements/smr/b2element_beam_cross_section.H"
30#include "model/b2element.H"
40namespace b2000::solver {
51class BeamCrossSectionSolver :
public Solver {
53 using mrbc_t = TypedModelReductionBoundaryCondition<double>;
54 using type_t = ObjectTypeComplete<BeamCrossSectionSolver, Solver::type_t>;
56 void solve()
override {
57 while (solve_iteration()) { ; }
60 bool solve_iteration()
override {
63 if (case_iterator_.get() ==
nullptr) {
66 case_ = case_iterator_->next();
67 if (!
case_) {
return false; }
73 <<
" but the beam cross section solver only handle a case with one stage of size "
74 "equal to one. The specified stage size is ignored."
81 <<
" but the beam cross section solver only handle a case with one stage of size "
82 "equal to one. The extra stages are ignored."
88 SolutionBeamCrossSection* solution =
90 if (solution ==
nullptr) {
91 TypeError() <<
"The solver only accept a solution of type SolutionBeamCrossSection"
98 mrbc_t* mrbc = &
dynamic_cast<mrbc_t&
>(
100 "TypedModelReductionBoundaryConditionListComponent" + type_name<double>())));
101 b2linalg::Vector<double, b2linalg::Vdense> r(number_of_dof);
102 b2linalg::Matrix<double, b2linalg::Mcompressed_col> trans_R;
103 mrbc->get_linear_value(r, trans_R);
110 bool n1_lookdof1 =
false;
111 std::pair<int, const double*> coor1;
113 Domain::node_iterator i = domain.get_node_iterator();
114 for (Node* n = i->next(); n !=
nullptr; n = i->next()) {
115 coor1 = n->get_coor<
double>();
116 if (coor1.first == 3 && trans_R.get_nb_nonzero(coor1.second[0]) == 0) {
124 Domain::node_iterator i = domain.get_node_iterator();
125 for (Node* n = i->next(); n !=
nullptr; n = i->next()) {
126 coor1 = n->get_coor<
double>();
127 if (coor1.first == 3) {
133 if (n1 ==
nullptr) { Exception() <<
THROW; }
137 Domain::node_iterator i = domain.get_node_iterator();
138 for (Node* n = i->next(); n !=
nullptr; n = i->next()) {
139 std::pair<int, const double*> coor2 = n->get_coor<
double>();
140 if (coor2.first == 3) {
142 sub_3(coor1.second, coor2.second, tmp);
143 double dtmp =
dot_3(tmp, tmp);
151 if (n2 ==
nullptr) { Exception() <<
THROW; }
153 b2linalg::Index ind(5);
154 n2->get_global_dof_numbering(&ind[2]);
155 n1->get_global_dof_numbering(&ind[0]);
156 if (n1_lookdof1) { ind.erase(ind.begin()); }
158 std::set<size_t> col_to_remove;
159 for (
size_t i = 0; i != ind.size(); ++i) {
162 const size_t nbz = trans_R.get_col_value(ind[i], rowind, value);
163 if (nbz == 0) { Exception() <<
THROW; }
164 col_to_remove.insert(rowind, rowind + nbz);
166 ind.assign(col_to_remove.begin(), col_to_remove.end());
167 trans_R.remove_row(ind);
170 double neutral_point[2];
172 double inertia_point[2];
173 double inertia_moment[3];
174 b2linalg::Matrix<double> u;
175 b2linalg::Matrix<double> lambda;
176 b2linalg::Vector<double> lambdad;
177 b2linalg::Matrix<double> strain[7];
178 b2linalg::Matrix<double> stress[7];
181 logger, *
case_,
model_, domain, trans_R, neutral_point, mass, inertia_point,
182 inertia_moment, u, lambda, lambdad, strain, stress);
184 solution->set_solution(
185 neutral_point, mass, inertia_point, inertia_moment, u, strain, stress, lambda,
189 solution->terminate_case(
true, attributes);
195 static void solve_static(
196 logging::Logger& logger, Case&
case_, Model* model, Domain& domain,
197 b2linalg::Matrix<double, b2linalg::Mcompressed_col>& trans_R,
double neutral_point[2],
198 double& inertia_mass,
double inertia_point[2],
double inertia_moment[3],
199 b2linalg::Matrix<double>& u, b2linalg::Matrix<double>& lambda,
200 b2linalg::Vector<double>& lambdad, b2linalg::Matrix<double> strain[7],
201 b2linalg::Matrix<double> stress[7]);
209void b2000::solver::BeamCrossSectionSolver::solve_static(
210 logging::Logger& logger, Case& case_, Model* model, Domain& domain,
211 b2linalg::Matrix<double, b2linalg::Mcompressed_col>& trans_R,
double neutral_point[2],
212 double& inertia_mass,
double inertia_point[2],
double inertia_moment[3],
213 b2linalg::Matrix<double>& u, b2linalg::Matrix<double>& lambda,
214 b2linalg::Vector<double>& lambdad, b2linalg::Matrix<double> strain[7],
215 b2linalg::Matrix<double> stress[7]) {
216 logger << logging::info <<
"Start the beam cross section solver" << logging::LOGFLUSH;
218 const size_t number_of_dof = domain.get_number_of_dof();
220 const bool log_el_flag = logger.is_enabled_for(logging::data);
221 logger << logging::info <<
"Computation of centre, first and second moment of area"
222 << logging::LOGFLUSH;
224 neutral_point[0] = neutral_point[1] = 0;
226 inertia_point[0] = inertia_point[1] = 0;
229 Domain::element_iterator i = domain.get_element_iterator();
230 for (Element* e = i->next(); e !=
nullptr; e = i->next()) {
231 static_cast<BeamCrossSectionBaseElement&
>(*e).add_value_0(
232 model, area, neutral_point, inertia_mass, inertia_point);
234 neutral_point[0] /= area;
235 neutral_point[1] /= area;
236 if (inertia_mass > 0) {
237 inertia_point[0] = inertia_point[0] / inertia_mass - neutral_point[0];
238 inertia_point[1] = inertia_point[1] / inertia_mass - neutral_point[1];
242 double inertia_axis[2][2];
244 double inertia[3] = {};
245 std::fill_n(inertia_moment, 3, 0);
246 Domain::element_iterator i = domain.get_element_iterator();
247 for (Element* e = i->next(); e !=
nullptr; e = i->next()) {
248 static_cast<BeamCrossSectionBaseElement&
>(*e).add_value_01(
249 model, neutral_point, inertia, inertia_moment);
253 double m[2][2] = {{inertia[0], inertia[2]}, {inertia[2], inertia[1]}};
258 for (
int j = 0; j != 2; ++j) { inertia_axis[1][j] *= -1; }
263 logger << logging::info <<
"Element matrix assembly" << logging::LOGFLUSH;
266 for (
int i = 0; i != 4; ++i) { trans_R.push_back(trans_R.size1(), trans_R.size2(), 1); }
268 size_t K_augm_size = trans_R.size1();
269 b2linalg::Matrix<double, b2linalg::Msym_compressed_col_update_inv> K_augm(
270 K_augm_size, domain.get_dof_connectivity_type(), case_);
271 domain.set_dof(b2linalg::Vector<double, b2linalg::Vdense_constref>::null);
273 Domain::element_iterator i = domain.get_element_iterator();
274 b2linalg::Index index;
275 b2linalg::Matrix<double, b2linalg::Mpacked> Ke;
276 for (Element* e = i->next(); e !=
nullptr; e = i->next()) {
277 static_cast<BeamCrossSectionBaseElement&
>(*e).add_value_1(
278 model, neutral_point, inertia_axis, number_of_dof, index, Ke);
280 trans_R * StructuredMatrix(number_of_dof + 4, index, Ke) * transposed(trans_R);
282 b2linalg::Matrix<double> tmp(Ke);
283 logger << logging::data <<
"elementary second variation "
284 << logging::DBName(
"ELSV", 0, e->get_object_name()) << tmp
285 <<
" of element id " << e->get_object_name() << logging::LOGFLUSH;
290 logger << logging::info <<
"First system resolution" << logging::LOGFLUSH;
292 b2linalg::Matrix<double> v(number_of_dof + 4, 6);
295 b2linalg::Matrix<double> v_augm(K_augm.size1(), 4);
296 for (
int i = 0; i != 4; ++i) { v_augm(K_augm.size1() - 4 + i, i) = 1; }
297 v_augm = b2linalg::inverse(K_augm) * v_augm;
298 v(b2linalg::Interval(2, 6)) = transposed(trans_R) * v_augm;
301 for (
int j = 0; j != 4; ++j) {
302 const int jj = j == 0 ? 0 : j + 2;
303 for (
int i = 0; i != 4; ++i) {
304 const int ii = i == 0 ? 0 : i + 2;
305#ifdef TEST_WITOUT_SYMMETRISATION
306 lambda(ii, jj) = v(number_of_dof + i, jj);
308 lambda(ii, jj) = 0.5 * (v(number_of_dof + i, jj) + v(number_of_dof + j, ii));
313 logger << logging::info <<
"Factorisation and first computation of beta" << logging::LOGFLUSH;
315 b2float128 beta[6][6] = {};
317 const bool beta_cd[6][6] = {{1, 0, 0, 1, 1, 1}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
318 {1, 0, 0, 1, 1, 1}, {1, 0, 0, 1, 1, 1}, {1, 0, 0, 1, 1, 1}};
319 const int beta_c[] = {0, 3, 4, 5};
320 const int beta_d[] = {0, 3, 4, 5};
321 Domain::element_iterator i = domain.get_element_iterator();
322 for (Element* e = i->next(); e !=
nullptr; e = i->next()) {
323 static_cast<BeamCrossSectionBaseElement&
>(*e).add_value_2(
324 model, neutral_point, inertia_axis, v, lambda, beta_cd, 4, beta_c, 4, beta_d,
328 for (
int j = 0; j != 4; ++j) {
329 const int jj = j == 0 ? 0 : j + 2;
330#ifdef TEST_WITOUT_SYMMETRISATION
331 lambda(1, jj) = beta[jj][5];
332 lambda(2, jj) = -beta[jj][4];
334 lambda(1, jj) = lambda(jj, 1) = beta[jj][5];
335 lambda(2, jj) = lambda(jj, 2) = -beta[jj][4];
339 logger << logging::info <<
"Second system resolution" << logging::LOGFLUSH;
341 b2linalg::Matrix<double> u(number_of_dof + 4, 2);
342 Domain::element_iterator i = domain.get_element_iterator();
343 for (Element* e = i->next(); e !=
nullptr; e = i->next()) {
344 static_cast<BeamCrossSectionBaseElement&
>(*e).add_value_3(
345 model, neutral_point, inertia_axis, number_of_dof, v, lambda, beta, u);
348 b2linalg::Matrix<double> u_augm;
349 u_augm = trans_R * u;
350 u_augm = b2linalg::inverse(K_augm) * u_augm;
351 v(b2linalg::Interval(1, 3)) = transposed(trans_R) * u_augm;
353 for (
int j = 1; j != 3; ++j) {
354 for (
int i = 0; i != 4; ++i) {
355 const int ii = i == 0 ? 0 : i + 2;
356#ifdef TEST_WITOUT_SYMMETRISATION
357 lambda(ii, j) = v(number_of_dof + i, j);
359 lambda(ii, j) = 0.5 * (lambda(ii, j) + v(number_of_dof + i, j));
360 lambda(j, ii) = 0.5 * (lambda(j, ii) + v(number_of_dof + i, j));
366 u.resize(number_of_dof, 7);
367 for (
int i = 0; i != 6; ++i) {
368 const double tmp1[3] = {double(beta[i][0]), double(beta[i][1]), double(beta[i][2])};
369 double tmp2[3] = {double(beta[i][3]), double(beta[i][4]), double(beta[i][5])};
371 Domain::node_iterator iter = domain.get_node_iterator();
372 for (Node* n = iter->next(); n !=
nullptr; n = iter->next()) {
374 const double* ptr = n->get_coor<
double>().second;
375 const double tmp4[3] = {0, ptr[1] - neutral_point[0], ptr[2] - neutral_point[1]};
377 const size_t pos = n->get_global_dof_numbering().first;
378 for (
int ii = 0; ii != 3; ++ii) {
379 u(pos + ii, i) = v(pos + ii, i) + tmp1[ii] + tmp3[ii];
384 logger << logging::info <<
"Second computation of beta" << logging::LOGFLUSH;
386 const bool beta_cd[6][6] = {{0, 1, 1, 0, 0, 0}, {1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1},
387 {0, 1, 1, 0, 0, 0}, {0, 1, 1, 0, 0, 0}, {0, 1, 1, 0, 0, 0}};
388 const int beta_c[] = {0, 1, 2, 3, 4, 5};
389 const int beta_d[] = {0, 1, 2, 3, 4, 5};
390 Domain::element_iterator i = domain.get_element_iterator();
391 for (Element* e = i->next(); e !=
nullptr; e = i->next()) {
392 static_cast<BeamCrossSectionBaseElement&
>(*e).add_value_2(
393 model, neutral_point, inertia_axis, v, lambda, beta_cd, 6, beta_c, 6, beta_d,
397 lambda(1, 1) = beta[5][1] + beta[1][5];
398 lambda(2, 1) = beta[5][2] - beta[1][4];
399 lambda(1, 2) = -beta[4][1] + beta[2][5];
400 lambda(2, 2) = -beta[4][2] - beta[2][4];
401#ifndef TEST_WITOUT_SYMMETRISATION
402 lambda(2, 1) = 0.5 * (lambda(2, 1) + lambda(1, 2));
403 lambda(1, 2) = lambda(2, 1);
406 logger << logging::info <<
"Strain and stress computation" << logging::LOGFLUSH;
408 const size_t number_of_node = domain.get_number_of_nodes();
410 for (
int i = 0; i != 7; ++i) {
411 strain[i].resize(6, number_of_node);
412 stress[i].resize(3, number_of_node);
416 std::vector<size_t> node_weight(number_of_dof);
417 std::vector<std::pair<const Node*, const Node*> > slave_nodes;
418 domain.get_slave_node(slave_nodes);
420 Domain::element_iterator i = domain.get_element_iterator();
421 for (Element* e = i->next(); e !=
nullptr; e = i->next()) {
422 static_cast<BeamCrossSectionBaseElement&
>(*e).add_value_4(
423 model, neutral_point, inertia_axis, v, lambda, beta, node_weight, strain, stress);
426 for (
size_t ptr = 0; ptr != slave_nodes.size(); ++ptr) {
427 const size_t sn = slave_nodes[ptr].first->get_id();
428 const size_t mn = slave_nodes[ptr].second->get_id();
429 node_weight[mn] += node_weight[sn];
430 for (
int i = 0; i != 6; ++i) {
431 for (
int j = 0; j != 6; ++j) { strain[i](j, mn) += strain[i](j, sn); }
432 for (
int j = 0; j != 3; ++j) { stress[i](j, mn) += stress[i](j, sn); }
436 for (
size_t k = 0; k != number_of_node; ++k) {
437 const double s = 1.0 / node_weight[k];
438 for (
int i = 0; i != 6; ++i) {
439 for (
int j = 0; j != 6; ++j) { strain[i](j, k) *= s; }
440 for (
int j = 0; j != 3; ++j) { stress[i](j, k) *= s; }
444 for (
size_t ptr = 0; ptr != slave_nodes.size(); ++ptr) {
445 const size_t sn = slave_nodes[ptr].first->get_id();
446 const size_t mn = slave_nodes[ptr].second->get_id();
447 for (
int i = 0; i != 6; ++i) {
448 for (
int j = 0; j != 6; ++j) { strain[i](j, sn) = strain[i](j, mn); }
449 for (
int j = 0; j != 3; ++j) { stress[i](j, sn) = stress[i](j, mn); }
454 logger << logging::info <<
"Computation of f due to the initial stress and bc"
455 << logging::LOGFLUSH;
457 std::fill_n(f, 6, 0);
459 Domain::element_iterator i = domain.get_element_iterator();
460 for (Element* e = i->next(); e !=
nullptr; e = i->next()) {
461 static_cast<BeamCrossSectionBaseElement&
>(*e).add_value_5(
462 model, neutral_point, inertia_axis, f);
466 b2linalg::Vector<double> vd(trans_R.size2());
468 logger << logging::info <<
"Third system resolution due to initial stress and bc"
469 << logging::LOGFLUSH;
471 b2linalg::Vector<double> value(number_of_dof + 4);
472 Domain::element_iterator i = domain.get_element_iterator();
473 for (Element* e = i->next(); e != 0; e = i->next()) {
474 static_cast<BeamCrossSectionBaseElement&
>(*e).add_value_6(
475 model, neutral_point, inertia_axis, number_of_dof, f, u, stress, value);
478 b2linalg::Vector<double> u_augm;
479 u_augm = trans_R * value;
480 u_augm = b2linalg::inverse(K_augm) * u_augm;
481 vd = transposed(trans_R) * u_augm;
484 lambdad[0] = vd[number_of_dof];
485 for (
int i = 1; i != 4; ++i) { lambdad[i + 2] = vd[number_of_dof + i]; }
487 b2linalg::Matrix<double> u_augm(trans_R.size1(), 5);
488 u_augm[4] = trans_R * value;
489 for (
int i = 0; i != 4; ++i) { u_augm(trans_R.size1() - 4 + i, i) = 1; }
490 u_augm = b2linalg::inverse(K_augm) * u_augm;
492 b2linalg::Vector<double> lm;
493 b2linalg::Interval int1(K_augm.size1() - 4, K_augm.size1());
498 lm = u_augm[4](int1);
500 4, 1, &u_augm(K_augm.size1() - 4, 0), u_augm.size1(), ipiv, &lm[0], 4, info);
501 if (info != 0) { Exception() <<
THROW; }
504 u_augm[4] = trans_R * value;
505 u_augm[4](int1) -= lm;
507 b2linalg::Vector<double> tmp;
508 tmp = b2linalg::inverse(K_augm) * u_augm[4];
509 vd = transposed(trans_R) * tmp;
514 for (
int i = 1; i != 4; ++i) { lambdad[i + 2] = lm[i]; }
519 for (
int i = 0; i != 6; ++i) { lambdad[i] = f[i]; }
522 logger << logging::info <<
"Strain and stress computation due to initial stress and bc"
523 << logging::LOGFLUSH;
525 b2linalg::Vector<double> value;
526 Domain::element_iterator i = domain.get_element_iterator();
527 for (Element* e = i->next(); e !=
nullptr; e = i->next()) {
528 static_cast<BeamCrossSectionBaseElement&
>(*e).add_value_7(
529 model, neutral_point, inertia_axis, f, u, vd,
530 vd(b2linalg::Interval(number_of_dof, number_of_dof + 4)), strain[6], stress[6]);
533 for (
size_t ptr = 0; ptr != slave_nodes.size(); ++ptr) {
534 const size_t sn = slave_nodes[ptr].first->get_id();
535 const size_t mn = slave_nodes[ptr].second->get_id();
536 for (
int j = 0; j != 6; ++j) { strain[6](j, mn) += strain[6](j, sn); }
537 for (
int j = 0; j != 3; ++j) { stress[6](j, mn) += stress[6](j, sn); }
540 for (
size_t k = 0; k != number_of_node; ++k) {
541 const double s = 1.0 / node_weight[k];
542 for (
int j = 0; j != 6; ++j) { strain[6](j, k) *= s; }
543 for (
int j = 0; j != 3; ++j) { stress[6](j, k) *= s; }
546 for (
size_t ptr = 0; ptr != slave_nodes.size(); ++ptr) {
547 const size_t sn = slave_nodes[ptr].first->get_id();
548 const size_t mn = slave_nodes[ptr].second->get_id();
549 for (
int i = 0; i != 6; ++i) {
550 for (
int j = 0; j != 6; ++j) { strain[6](j, sn) = strain[6](j, mn); }
551 for (
int j = 0; j != 3; ++j) { stress[6](j, sn) = stress[6](j, mn); }
557 logger << logging::info <<
"beta computation due to initial stress and bc" << logging::LOGFLUSH;
560 std::fill_n(betad, 6, 0);
561 Domain::element_iterator i = domain.get_element_iterator();
562 for (Element* e = i->next(); e != 0; e = i->next()) {
563 static_cast<BeamCrossSectionBaseElement&
>(*e).add_value_8(
564 model, neutral_point, inertia_axis, u, vd, stress, stress[6], betad);
566 lambdad[1] = betad[5];
567 lambdad[2] = -betad[4];
570 const double tmp1[3] = {betad[0], betad[1], betad[2]};
571 double tmp2[3] = {betad[3], betad[4], betad[5]};
573 Domain::node_iterator iter = domain.get_node_iterator();
574 for (Node* n = iter->next(); n != 0; n = iter->next()) {
576 const double* ptr = n->get_coor<
double>().second;
577 const double tmp4[3] = {0, ptr[1] - neutral_point[0], ptr[2] - neutral_point[1]};
579 const size_t pos = n->get_global_dof_numbering().first;
580 for (
int ii = 0; ii != 3; ++ii) { u(pos + ii, 6) = vd[pos + ii] + tmp1[ii] + tmp3[ii]; }
587 for (
int i = 0; i != 7; ++i) {
588 Domain::node_iterator iter = domain.get_node_iterator();
589 for (Node* n = iter->next(); n !=
nullptr; n = iter->next()) {
590 const size_t pos = n->get_global_dof_numbering().first;
591 const double tmp[2] = {u(pos + 1, i), u(pos + 2, i)};
592 u(pos + 1, i) = inertia_axis[0][0] * tmp[0] + inertia_axis[1][0] * tmp[1];
593 u(pos + 2, i) = inertia_axis[0][1] * tmp[0] + inertia_axis[1][1] * tmp[1];
600 for (
size_t k = 0; k != number_of_node; ++k) {
601 for (
int i = 0; i != 7; ++i) {
602 const double tmp[2] = {stress[i](1, k), stress[i](2, k)};
603 stress[i](1, k) = inertia_axis[0][0] * tmp[0] + inertia_axis[1][0] * tmp[1];
604 stress[i](2, k) = inertia_axis[0][1] * tmp[0] + inertia_axis[1][1] * tmp[1];
611 b2linalg::Matrix<double> trans(6, 6);
612 trans(0, 0) = trans(3, 3) = 1;
613 for (
int j = 0; j != 2; ++j) {
614 for (
int i = 0; i != 2; ++i) {
615 trans(i + 1, j + 1) = trans(i + 4, j + 4) = inertia_axis[j][i];
626 b2linalg::Matrix<double> tmp;
627 tmp = trans * lambda;
628 lambda = tmp * transposed(trans);
632 b2linalg::Vector<double> tmp;
633 tmp = trans * lambdad;
634 lambdad = tmp * transposed(trans);
638 b2linalg::Vector<double> tmp;
639 tmp = transposed(trans) * lambdad;
640 lambdad = tmp * trans;
646 std::cout <<
"beta=" << std::endl;
647 for (
int i = 0; i != 6; ++i) {
648 for (
int j = 0; j != 6; ++j) { std::cout << double(beta[j][i]) <<
" "; }
649 std::cout << std::endl;
652 for (
int i = 0; i != 3; ++i) {
653 sum[0] += beta[i][i];
654 sum[1] += beta[i + 3][i + 3];
655 sum[2] += beta[i][i + 3];
656 sum[3] += beta[i + 3][i];
658 std::cout <<
"localisation prop: " << sum[0] <<
" " << sum[1] <<
" " << sum[2] <<
" " << sum[3]
660 std::cout <<
"lambda=\n" << lambda << std::endl;
663 b2linalg::Matrix<double, b2linalg::Mrectangle_increment_ref>(lambda).in_place_invert();
666 b2linalg::Vector<double> tmp;
667 tmp = lambda * lambdad;
673 std::cout << lambda << std::endl;
676 b2linalg::Matrix<double> lambda_svd(lambda);
678 Vector<double> eigenvalue(6);
680 lapack::syev(
'V',
'L', 6, &lambda_svd(0, 0), 6, &eigenvalue[0], work, 48, info);
682 std::cout <<
"eigenvalue=\n" << eigenvalue << std::endl;
683 std::cout <<
"lambda_svd=\n" << lambda_svd << std::endl;
#define THROW
Definition b2exception.H:198
Interface to C++ representations of FE solvers.
virtual double get_stage_size(int stage=-1) const =0
virtual std::string get_id() const =0
virtual size_t get_number_of_stage() const =0
virtual void warn_on_non_used_key() const =0
virtual size_t get_number_of_dof() const =0
virtual Solution & get_solution()=0
virtual CaseList & get_case_list()=0
virtual void set_case(Case &case_)=0
virtual Domain & get_domain()=0
virtual ModelReductionBoundaryCondition & get_model_reduction_boundary_condition(ObjectTypeIncomplete< ModelReductionBoundaryCondition > *bc_type)=0
Case * case_
This also.
Definition b2solver.H:93
Model * model_
Definition b2solver.H:91
Logger & get_logger(const std::string &logger_name="")
Definition b2logging.H:829
void sub_3(const T1 v1[3], const T2 v2[3], T3 dest[3])
Definition b2tensor_calculus.H:239
void eigenvector_2(const std::array< std::array< T, 2 >, 2 > &matrix, std::array< T, 2 > &eigenvalues, std::array< std::array< T, 2 >, 2 > &eigenvector)
Definition b2tensor_calculus.H:181
void outer_product_3(const T1 a[3], const T2 b[3], T3 c[3])
Definition b2tensor_calculus.H:389
GenericException< TypeError_name > TypeError
Definition b2exception.H:325
T normalise_2(T a[2])
Definition b2tensor_calculus.H:460
T dot_3(const T a[3], const T b[3])
Definition b2tensor_calculus.H:328
T determinant_2_2(const T a[2][2])
Definition b2tensor_calculus.H:683