22#ifndef B2REISSNER_BEAM_PROPERTY_H_
23#define B2REISSNER_BEAM_PROPERTY_H_
28#include "b2ppconfig.h"
29#include "b2solid_mechanics.H"
30#include "model/b2element.H"
34#include "utils/b2beam_cross_sections.H"
39class ReissnerBeamPropertyBase :
virtual public SolidMechanics {
42 only_membrane_and_shear_components = 1,
43 all_but_membrane_and_shear_components = 2,
47 LinearType linear(
const int layer_id = -1)
const {
return nonlinear; }
49 bool isotropic(
const int layer_id = -1)
const {
return false; }
51 virtual bool path_dependent(
const int layer_id = -1)
const {
return false; }
55class ReissnerBeamProperty :
public ReissnerBeamPropertyBase {
102 virtual void get_value(
103 Model& model,
const bool linear,
const EquilibriumSolution equilibrium_solution,
104 const double time,
const double delta_time, GradientContainer* gradient_container,
105 SolverHints* solver_hints,
const Element& element,
const double element_coordinate,
106 const b2linalg::Vector<double, b2linalg::Vdense_constref> nodes_interpolation,
107 const T reference_to_undeformed_cross_section_rotator[3][3],
108 const T undeformed_to_deformed_cross_section_rotator[3][3],
109 const T strain_and_curvature[6],
const T acceleration[6],
110 const ReissnerBeamPropertyBase::Components components, T force_and_moment[6],
111 T d_force_and_moment_d_strain_and_curvature[6][6], T d_force_and_moment_d_time[6],
112 T inertia[6], T d_inertia_d_acceleration[3][3][3]) = 0;
114 virtual bool get_nodes_eccentricity_and_axe(
115 int nb_nodes,
const T node_coor[][3],
const double node_icoor[],
const T node_e3[][3],
116 T e1[3], T nodes_ecc[][3]) {
121 virtual const T* get_C()
const {
126 virtual void set_non_structural_mass(
const T& mass_,
const T inertia_point_[2]) {}
128 virtual void set_pre_stress(
const T& force,
const T coor[2]) {}
130 virtual void set_pre_stress(
const T force[3]) {}
137 virtual const T* get_cross_section_face_segment(
const int face_id)
const {
143 virtual bool get_nodes_neutral_point(
144 int nb_nodes,
const T node_coor[][3],
const double node_icoor[],
const T node_e3[][3],
145 T neutral_point[][2]) {
150 virtual void field_section_integration(
151 const double element_coordinate,
const T value[6],
const bool multiply_with_density,
156 virtual std::bitset<6> get_release_end_node_dof(
const int node_ind)
const {
157 Exception() <<
THROW;
158 return std::bitset<6>();
161 T get_prop_required(
const RTable rtable,
const std::string& s)
const {
162 if (rtable.has_key(s)) {
163 return rtable.get<T>(s);
165 Exception() <<
"Required beam section property " << s <<
" not found" <<
THROW;
172class ReissnerBeamConstantCrossSectionElasticProperty :
public ReissnerBeamProperty<T> {
174 ReissnerBeamConstantCrossSectionElasticProperty() {
175 std::fill_n(shear_center, 2, T(0));
176 std::fill_n(neutral_axis_point, 2, T(0));
177 std::fill_n(inertia_point, 2, T(0));
180 std::fill_n(ns_inertia_point, 2, T(0));
181 std::fill_n(pre_stress, 3, T(0));
191 bool get_nodes_neutral_point(
192 int nb_nodes,
const T node_coor[][3],
const double node_icoor[],
const T node_e3[][3],
193 T neutral_point[][2]) {
194 for (
int k = 0; k != nb_nodes; ++k) {
195 neutral_point[k][0] = neutral_axis_point[0];
196 neutral_point[k][1] = neutral_axis_point[1];
201 const T* get_C()
const {
return &C[0]; }
204 Model& model,
const bool linear,
const EquilibriumSolution equilibrium_solution,
205 const double time,
const double delta_time, GradientContainer* gradient_container,
206 SolverHints* solver_hints,
const Element& element,
const double element_coordinate,
207 const b2linalg::Vector<double, b2linalg::Vdense_constref> nodes_interpolation,
208 const T reference_to_undeformed_cross_section_rotator[3][3],
209 const T undeformed_to_deformed_cross_section_rotator[3][3],
210 const T strain_and_curvature[6],
const T acceleration[6],
211 const ReissnerBeamPropertyBase::Components components, T force_and_moment[6],
212 T d_force_and_moment_d_strain_and_curvature[6][6], T d_force_and_moment_d_time[6],
213 T inertia[6], T d_inertia_d_acceleration[3][3][3]) {
214 const bool neutral_axis_point_zero =
217 if (gradient_container !=
nullptr && reference_to_undeformed_cross_section_rotator != 0) {
218 static const GradientContainer::FieldDescription descr_mbase = {
220 "e1x.e1y.e1z.e2x.e2y.e2z.e3x.e3y.e3z",
221 "Material base vectors in the undeformed configuration",
230 reference_to_undeformed_cross_section_rotator[2],
231 reference_to_undeformed_cross_section_rotator[2] + 3, mbase[0]);
233 reference_to_undeformed_cross_section_rotator[0],
234 reference_to_undeformed_cross_section_rotator[0] + 3, mbase[1]);
236 reference_to_undeformed_cross_section_rotator[1],
237 reference_to_undeformed_cross_section_rotator[1] + 3, mbase[2]);
238 if (gradient_container->compute_field_value(descr_mbase.name)) {
239 gradient_container->set_field_value(descr_mbase, &mbase[0][0]);
243 if (force_and_moment) {
244 if (strain_and_curvature) {
245 if (components != this->only_membrane_and_shear_components) {
246 for (
int i = 3; i != 6; ++i) {
247 force_and_moment[i] = strain_and_curvature[i] * C[i];
249 force_and_moment[3] += strain_and_curvature[4] * C[7];
250 force_and_moment[4] += strain_and_curvature[3] * C[7];
252 std::fill(force_and_moment + 3, force_and_moment + 6, T(0));
254 if (components == this->only_membrane_and_shear_components
255 || components == this->all_components) {
256 if (neutral_axis_point_zero) {
257 for (
int i = 0; i != 3; ++i) {
258 force_and_moment[i] = C[i] * strain_and_curvature[i];
260 force_and_moment[0] += strain_and_curvature[1] * C[6];
261 force_and_moment[1] += strain_and_curvature[0] * C[6];
263 force_and_moment[0] =
264 C[0] * strain_and_curvature[0] + strain_and_curvature[1] * C[6];
265 force_and_moment[1] =
266 C[1] * strain_and_curvature[1] + strain_and_curvature[0] * C[6];
267 force_and_moment[2] = C[2]
268 * (strain_and_curvature[2]
269 + neutral_axis_point[1] * strain_and_curvature[3]
270 - neutral_axis_point[0] * strain_and_curvature[4]);
271 force_and_moment[3] += force_and_moment[2] * neutral_axis_point[1];
272 force_and_moment[4] += -force_and_moment[2] * neutral_axis_point[0];
275 std::fill(force_and_moment, force_and_moment + 3, T(0));
278 std::fill(force_and_moment, force_and_moment + 6, T(0));
280 if (components != this->only_membrane_and_shear_components) {
281 for (
int i = 0; i != 3; ++i) { force_and_moment[i] += pre_stress[i]; }
285 if (d_force_and_moment_d_strain_and_curvature) {
286 if (components == this->only_membrane_and_shear_components
287 || components == this->all_components) {
289 d_force_and_moment_d_strain_and_curvature[0],
290 d_force_and_moment_d_strain_and_curvature[6], T(0));
291 for (
int i = 0; i != 3; ++i) {
292 d_force_and_moment_d_strain_and_curvature[i][i] = C[i];
294 d_force_and_moment_d_strain_and_curvature[1][0] =
295 d_force_and_moment_d_strain_and_curvature[0][1] = C[6];
296 if (!neutral_axis_point_zero) {
297 d_force_and_moment_d_strain_and_curvature[3][2] =
298 d_force_and_moment_d_strain_and_curvature[2][3] =
299 C[2] * neutral_axis_point[1];
300 d_force_and_moment_d_strain_and_curvature[4][2] =
301 d_force_and_moment_d_strain_and_curvature[2][4] =
302 -C[2] * neutral_axis_point[0];
303 d_force_and_moment_d_strain_and_curvature[3][3] +=
304 C[2] * neutral_axis_point[1] * neutral_axis_point[1];
305 d_force_and_moment_d_strain_and_curvature[5][4] =
306 d_force_and_moment_d_strain_and_curvature[4][5] =
307 -C[2] * neutral_axis_point[0] * neutral_axis_point[1];
308 d_force_and_moment_d_strain_and_curvature[4][4] +=
309 C[2] * neutral_axis_point[0] * neutral_axis_point[0];
313 d_force_and_moment_d_strain_and_curvature[0],
314 d_force_and_moment_d_strain_and_curvature[6], T(0));
316 if (components != this->only_membrane_and_shear_components) {
317 for (
int i = 3; i != 6; ++i) {
318 d_force_and_moment_d_strain_and_curvature[i][i] += C[i];
320 d_force_and_moment_d_strain_and_curvature[3][4] += C[7];
321 d_force_and_moment_d_strain_and_curvature[4][3] += C[7];
325 const bool inertia_point_zero = inertia_point[0] == 0 && inertia_point[1] == 0;
326 const bool ns_inertia_point_zero = ns_inertia_point[0] == 0 && ns_inertia_point[1] == 0;
329 if (inertia_point_zero) {
330 for (
int i = 0; i != 3; ++i) { inertia[i] = mass * acceleration[i]; }
331 for (
int i = 0; i != 2; ++i) {
332 inertia[i + 3] = inertia_moment[i] * acceleration[i + 3];
334 inertia[5] = (inertia_moment[0] + inertia_moment[1]) * acceleration[5];
335 inertia[3] += inertia_moment[2] * acceleration[4];
336 inertia[4] += inertia_moment[2] * acceleration[3];
338 inertia[0] = mass * (acceleration[0] - inertia_point[1] * acceleration[5]);
339 inertia[1] = mass * (acceleration[1] + inertia_point[0] * acceleration[5]);
341 * (acceleration[2] + inertia_point[1] * acceleration[3]
342 - inertia_point[0] * acceleration[4]);
343 inertia[3] = inertia_moment[0] * acceleration[3]
344 + inertia_moment[2] * acceleration[4]
345 + inertia[2] * inertia_point[1];
346 inertia[4] = inertia_moment[1] * acceleration[4]
347 + inertia_moment[2] * acceleration[3]
348 - inertia[2] * inertia_point[0];
349 inertia[5] = (inertia_moment[0] + inertia_moment[1]) * acceleration[5]
350 - inertia[0] * inertia_point[1] + inertia[1] * inertia_point[1];
352 if (ns_inertia_point_zero) {
353 for (
int i = 0; i != 3; ++i) { inertia[i] += ns_mass * acceleration[i]; }
356 ns_mass * (acceleration[0] - ns_inertia_point[1] * acceleration[5]);
359 ns_mass * (acceleration[1] + ns_inertia_point[0] * acceleration[5]);
362 * (acceleration[2] + ns_inertia_point[1] * acceleration[3]
363 - ns_inertia_point[0] * acceleration[4]);
365 inertia[3] += i2 * ns_inertia_point[1];
366 inertia[4] += -i2 * ns_inertia_point[0];
367 inertia[5] += -i0 * ns_inertia_point[1] + i1 * ns_inertia_point[1];
370 std::fill(inertia, inertia + 6, T(0));
374 if (d_inertia_d_acceleration) {
375 std::fill(d_inertia_d_acceleration[0][0], d_inertia_d_acceleration[3][0], T(0));
376 for (
int i = 0; i != 3; ++i) { d_inertia_d_acceleration[0][i][i] = mass + ns_mass; }
377 for (
int i = 0; i != 2; ++i) { d_inertia_d_acceleration[2][i][i] = inertia_moment[i]; }
378 d_inertia_d_acceleration[2][2][2] = inertia_moment[0] + inertia_moment[1];
379 d_inertia_d_acceleration[2][1][0] = inertia_moment[2];
380 if (!inertia_point_zero) {
381 d_inertia_d_acceleration[1][0][2] =
382 mass * inertia_point[1] + ns_mass * ns_inertia_point[1];
383 d_inertia_d_acceleration[1][1][2] =
384 -mass * inertia_point[0] - ns_mass * ns_inertia_point[0];
385 d_inertia_d_acceleration[1][2][0] =
386 -mass * inertia_point[1] - ns_mass * ns_inertia_point[1];
387 d_inertia_d_acceleration[1][2][1] =
388 mass * inertia_point[0] + ns_mass * ns_inertia_point[0];
389 d_inertia_d_acceleration[2][0][0] +=
390 mass * inertia_point[1] * inertia_point[1]
391 + ns_mass * ns_inertia_point[1] * ns_inertia_point[1];
392 d_inertia_d_acceleration[2][1][0] +=
393 -mass * inertia_point[0] * inertia_point[1]
394 - -ns_mass * ns_inertia_point[0] * ns_inertia_point[1];
395 d_inertia_d_acceleration[2][1][1] +=
396 mass * inertia_point[0] * inertia_point[0]
397 + ns_mass * ns_inertia_point[0] * ns_inertia_point[0];
398 d_inertia_d_acceleration[2][2][2] +=
400 * (inertia_point[0] * inertia_point[0]
401 + inertia_point[1] * inertia_point[1])
403 * (ns_inertia_point[0] * ns_inertia_point[0]
404 + ns_inertia_point[1] * ns_inertia_point[1]);
406 d_inertia_d_acceleration[2][0][1] = d_inertia_d_acceleration[2][1][0];
409 if (d_force_and_moment_d_time) {
410 std::fill(d_force_and_moment_d_time, d_force_and_moment_d_time + 6, T(0));
413 if (gradient_container
414 && (components == this->only_membrane_and_shear_components
415 || components == this->all_components)) {
416 static const GradientContainer::FieldDescription force_beam_descr = {
417 "FORCE_SECTION_BEAM",
419 "Beam section forces",
426 if (gradient_container->compute_field_value(force_beam_descr.name)) {
428 C[2] * strain_and_curvature[2],
429 C[0] * strain_and_curvature[0] + strain_and_curvature[1] * C[6],
430 C[1] * strain_and_curvature[1] + strain_and_curvature[0] * C[6]};
431 gradient_container->set_field_value(force_beam_descr, force);
433 static const GradientContainer::FieldDescription moment_beam_descr = {
434 "MOMENT_SECTION_BEAM",
436 "Beam section moments",
443 if (gradient_container->compute_field_value(moment_beam_descr.name)) {
444 const T moment[3] = {
445 C[5] * strain_and_curvature[5],
446 C[3] * strain_and_curvature[3] + strain_and_curvature[4] * C[7],
447 C[4] * strain_and_curvature[4] + strain_and_curvature[3] * C[7]};
448 gradient_container->set_field_value(moment_beam_descr, moment);
452 reference_to_undeformed_cross_section_rotator,
453 undeformed_to_deformed_cross_section_rotator, strain_and_curvature,
458 void field_section_integration(
459 const double element_coordinate,
const T value[6],
const bool multiply_with_density,
461 if (multiply_with_density) {
463 force[0] = mass * (value[0] - inertia_point[1] * value[5]);
464 force[1] = mass * (value[1] + inertia_point[0] * value[5]);
466 mass * (value[2] + inertia_point[1] * value[3] - inertia_point[0] * value[4]);
467 force[3] = inertia_moment[0] * value[3] + inertia_moment[2] * value[4]
468 + force[2] * inertia_point[1];
469 force[4] = inertia_moment[1] * value[4] + inertia_moment[2] * value[3]
470 - value[2] * inertia_point[0];
471 force[5] = (inertia_moment[0] + inertia_moment[1]) * value[5]
472 - force[0] * inertia_point[1] + force[1] * inertia_point[1];
475 const T i0 = ns_mass * (value[0] - ns_inertia_point[1] * value[5]);
477 const T i1 = ns_mass * (value[1] + ns_inertia_point[0] * value[5]);
481 * (value[2] + ns_inertia_point[1] * value[3] - ns_inertia_point[0] * value[4]);
483 force[3] += i2 * ns_inertia_point[1];
484 force[4] += -i2 * ns_inertia_point[0];
485 force[5] += -i0 * ns_inertia_point[1] + i1 * ns_inertia_point[1];
487 force[0] = area * value[0];
488 force[1] = area * value[1];
489 force[2] = area * value[2];
493 virtual void set_gradient(
494 const T reference_to_undeformed_cross_section_rotator[3][3],
495 const T undeformed_to_deformed_cross_section_rotator[3][3],
496 const T strain_and_curvature[6], GradientContainer* gradient_container) {}
498 void set_non_structural_mass(
const T& mass_,
const T inertia_point_[2]) {
500 std::copy(inertia_point_, inertia_point_ + 2, ns_inertia_point);
503 void set_pre_stress(
const T& force,
const T coor[2]) {
504 pre_stress[2] = force;
506 pre_stress[0] = (coor[1] - neutral_axis_point[1]) * force;
507 pre_stress[1] = -(coor[0] - neutral_axis_point[0]) * force;
511 void set_pre_stress(
const T force[3]) {
512 pre_stress[2] = force[0];
513 pre_stress[0] = force[1];
514 pre_stress[1] = force[2];
519 T neutral_axis_point[2];
524 T ns_inertia_point[2];
531class ReissnerBeamVariableCrossSectionElasticProperty :
public ReissnerBeamProperty<T> {
533 bool get_nodes_neutral_point(
534 int nb_nodes,
const T node_coor[][3],
const double node_icoor[],
const T node_e3[][3],
535 T neutral_point[][2]) {
536 for (
int k = 0; k != nb_nodes; ++k) {
538 std::lower_bound(property_icoor.begin(), property_icoor.end(), node_icoor[k])
539 - property_icoor.begin();
540 const size_t i2 = i1 + 1;
542 (node_icoor[k] - property_icoor[i2]) / (property_icoor[i1] - property_icoor[i2]);
544 for (
int i = 0; i != 2; ++i) {
545 neutral_point[k][i] =
546 s1 *
property[i1].shear_center[i] + s2 *
property[i2].shear_center[i];
553 Model& model,
const bool linear,
const EquilibriumSolution equilibrium_solution,
554 const double time,
const double delta_time,
const Element& element,
555 const double element_coordinate,
556 const b2linalg::Vector<double, b2linalg::Vdense_constref> nodes_interpolation,
557 const T reference_to_undeformed_cross_section_rotator[3][3],
558 const T undeformed_to_deformed_cross_section_rotator[3][3],
559 const T strain_and_curvature[6],
const T acceleration[6],
560 const ReissnerBeamPropertyBase::Components components, T force_and_moment[6],
561 T d_force_and_moment_d_strain_and_curvature[6][6], T d_force_and_moment_d_time[6],
562 T inertia[6], T d_inertia_d_acceleration[3][3][3], GradientContainer* gradient_container,
563 SolverHints* solver_hints) {
565 std::lower_bound(property_icoor.begin(), property_icoor.end(), element_coordinate)
566 - property_icoor.begin();
567 const size_t i2 = i1 + 1;
569 (element_coordinate - property_icoor[i2]) / (property_icoor[i1] - property_icoor[i2]);
572 ReissnerBeamConstantCrossSectionElasticProperty<T> cs;
573 for (
int i = 0; i != 2; ++i) {
574 cs.neutral_axis_point[i] =
575 s1 *
property[i1].neutral_axis_point[i] + s2 *
property[i2].neutral_axis_point[i];
576 cs.inertia_point[i] =
577 s1 *
property[i1].inertia_point[i] + s2 *
property[i2].inertia_point[i];
578 cs.ns_inertia_point[i] =
579 s1 *
property[i1].ns_inertia_point[i] + s2 *
property[i2].ns_inertia_point[i];
581 for (
int i = 0; i != 7; ++i) { cs.C[i] = s1 *
property[i1].C[i] + s2 *
property[i2].C[i]; }
582 cs.mass = s1 *
property[i1].mass + s2 *
property[i2].mass;
583 cs.ns_mass = s1 *
property[i1].ns_mass + s2 *
property[i2].ns_mass;
584 for (
int i = 0; i != 3; ++i) {
585 cs.inertia_moment[i] =
586 s1 *
property[i1].inertia_moment[i] + s2 *
property[i2].inertia_moment[i];
588 for (
int i = 0; i != 3; ++i) {
589 cs.pre_stress[i] = s1 *
property[i1].pre_stress[i] + s2 *
property[i2].pre_stress[i];
593 model, linear, equilibrium_solution, time, delta_time, gradient_container,
594 solver_hints, element, element_coordinate, nodes_interpolation,
595 reference_to_undeformed_cross_section_rotator,
596 undeformed_to_deformed_cross_section_rotator, strain_and_curvature, acceleration,
597 components, force_and_moment, d_force_and_moment_d_strain_and_curvature,
598 d_force_and_moment_d_time, inertia, d_inertia_d_acceleration);
601 void field_section_integration(
602 const T element_coordinate,
const T value[6],
const bool multiply_with_density,
605 std::lower_bound(property_icoor.begin(), property_icoor.end(), element_coordinate)
606 - property_icoor.begin();
607 const size_t i2 = i1 + 1;
609 (element_coordinate - property_icoor[i2]) / (property_icoor[i1] - property_icoor[i2]);
612 ReissnerBeamConstantCrossSectionElasticProperty<T> cs;
613 for (
int i = 0; i != 2; ++i) {
614 cs.neutral_axis_point[i] =
615 s1 *
property[i1].neutral_axis_point[i] + s2 *
property[i2].neutral_axis_point[i];
616 cs.inertia_point[i] =
617 s1 *
property[i1].inertia_point[i] + s2 *
property[i2].inertia_point[i];
618 cs.ns_inertia_point[i] =
619 s1 *
property[i1].ns_inertia_point[i] + s2 *
property[i2].ns_inertia_point[i];
621 for (
int i = 0; i != 7; ++i) { cs.C[i] = s1 *
property[i1].C[i] + s2 *
property[i2].C[i]; }
622 cs.mass = s1 *
property[i1].mass + s2 *
property[i2].mass;
623 cs.ns_mass = s1 *
property[i1].ns_mass + s2 *
property[i2].ns_mass;
624 for (
int i = 0; i != 3; ++i) {
625 cs.inertia_moment[i] =
626 s1 *
property[i1].inertia_moment[i] + s2 *
property[i2].inertia_moment[i];
628 for (
int i = 0; i != 3; ++i) {
629 cs.pre_stress[i] = s1 *
property[i1].pre_stress[i] + s2 *
property[i2].pre_stress[i];
632 cs.field_section_integration(element_coordinate, value, multiply_with_density, force);
636 struct CrossSectionProperty {
638 T neutral_axis_point[2];
643 T ns_inertia_point[2];
647 std::vector<T> property_icoor;
648 std::vector<CrossSectionProperty> property;
652class ReissnerBeamElasticConstantProperty
653 :
public ReissnerBeamConstantCrossSectionElasticProperty<T> {
655 ReissnerBeamElasticConstantProperty() {
656 this->mass = this->ns_mass = 0;
657 std::fill_n(this->inertia_point, 2, T(0));
658 std::fill_n(this->inertia_moment, 3, T(0));
659 std::fill_n(this->ns_inertia_point, 2, T(0));
660 std::fill_n(this->pre_stress, 3, T(0));
664 const T* get_C()
const {
return &this->C[0]; }
666 void print_constants() {
667 std::cerr <<
"ReissnerBeamElasticConstantPropertyCross section " << std::endl
668 <<
"inertia_point=" << this->inertia_point[0] <<
" " << this->inertia_point[1]
670 <<
"shear_center=" << this->shear_center[0] <<
" " << this->shear_center[1]
674 void set_static_property(
675 const T neutral_axis_point_[2],
const T shear_center_[2], T traction,
const T bending[3],
676 T torsion,
const T shear[3]) {
677 this->shear_center[0] = shear_center_[0];
678 this->shear_center[1] = shear_center_[1];
679 this->neutral_axis_point[0] = neutral_axis_point_[0];
680 this->neutral_axis_point[1] = neutral_axis_point_[1];
681 this->C[0] = shear[0];
682 this->C[1] = shear[1];
683 this->C[2] = traction;
684 this->C[3] = bending[0];
685 this->C[4] = bending[1];
686 this->C[5] = torsion;
687 this->C[6] = shear[2];
688 this->C[7] = bending[2];
697 void set_dynamic_property(
698 const T mass_,
const T mass_inertia_point_[2],
const T mass_inertia_moment_[3],
699 T ns_mass_,
const T ns_inertia_point_[2]) {
701 this->inertia_point[0] = mass_inertia_point_[0];
702 this->inertia_point[1] = mass_inertia_point_[1];
703 this->inertia_moment[0] = mass_inertia_moment_[0];
704 this->inertia_moment[1] = mass_inertia_moment_[1];
705 this->inertia_moment[2] = mass_inertia_moment_[2];
706 this->ns_mass = ns_mass_;
707 this->ns_inertia_point[0] = ns_inertia_point_[0];
708 this->ns_inertia_point[1] = ns_inertia_point_[1];
712 const T reference_to_undeformed_cross_section_rotator[3][3],
713 const T undeformed_to_deformed_cross_section_rotator[3][3],
714 const T strain_and_curvature[6], GradientContainer* gradient_container) {}
722class ReissnerBeamElasticBarProperty :
public ReissnerBeamConstantCrossSectionElasticProperty<T> {
725 const T& E,
const T& p,
const T& density,
const T& nsmass,
const RTable& rtable,
726 const RTable& frtable) {
727 const T G = E / (2 * (1 + p));
730 BeamCrossSectionBar<T> section;
731 section.load(rtable);
732 this->C[0] = G * section.A * section.K1;
733 this->C[1] = G * section.A * section.K2;
734 this->C[2] = E * section.A;
735 this->C[3] = E * section.Iyy;
736 this->C[4] = E * section.Izz;
737 this->C[5] = G * section.It;
740 this->mass = density * section.A;
741 this->ns_mass = nsmass;
742 this->inertia_moment[0] = density * section.Iyy;
743 this->inertia_moment[1] = density * section.Izz;
744 this->inertia_moment[2] = 0;
745 this->area = section.A;
750 const T* get_C()
const {
return &this->C[0]; }
753 const T reference_to_undeformed_cross_section_rotator[3][3],
754 const T undeformed_to_deformed_cross_section_rotator[3][3],
755 const T strain_and_curvature[6], GradientContainer* gradient_container) {}
759class ReissnerBeamElasticBoxProperty :
public ReissnerBeamConstantCrossSectionElasticProperty<T> {
762 const T& E,
const T& p,
const T& density,
const T& nsmass,
const RTable& rtable,
763 const RTable& frtable) {
765 BeamCrossSectionBox<T> section;
766 section.load(rtable);
767 const T G = E / (2 * (1 + p));
768 this->C[0] = G * section.A * section.K1;
769 this->C[1] = G * section.A * section.K2;
770 this->C[2] = E * section.A;
771 this->C[3] = E * section.Iyy;
772 this->C[4] = E * section.Izz;
773 this->C[5] = G * section.It;
776 this->mass = density * section.A;
777 this->ns_mass = nsmass;
778 this->inertia_moment[0] = density * section.Iyy;
779 this->inertia_moment[1] = density * section.Izz;
780 this->inertia_moment[2] = 0;
781 this->area = section.A;
785 const T* get_C() {
return &this->C[0]; }
788 const T reference_to_undeformed_cross_section_rotator[3][3],
789 const T undeformed_to_deformed_cross_section_rotator[3][3],
790 const T strain_and_curvature[6], GradientContainer* gradient_container) {}
794class ReissnerBeamElasticTubeProperty :
public ReissnerBeamConstantCrossSectionElasticProperty<T> {
797 const T& E,
const T& p,
const T& density,
const T& nsmass,
const RTable& rtable,
798 const RTable& frtable) {
799 BeamCrossSectionTube<T> section;
800 section.load(rtable);
801 const T G = E / (2 * (1 + p));
802 this->C[0] = G * section.A * section.K1;
803 this->C[1] = this->C[0];
804 this->C[2] = E * section.A;
805 this->C[3] = E * section.Iyy;
806 this->C[4] = this->C[3];
807 this->C[5] = G * section.It;
810 this->mass = density * section.A;
811 this->ns_mass = nsmass;
812 this->inertia_moment[0] = density * section.Iyy;
813 this->inertia_moment[1] = this->inertia_moment[0];
814 this->inertia_moment[2] = 0;
815 this->area = section.A;
819 const T* get_C()
const {
return &this->C[0]; }
822 const T reference_to_undeformed_cross_section_rotator[3][3],
823 const T undeformed_to_deformed_cross_section_rotator[3][3],
824 const T strain_and_curvature[6], GradientContainer* gradient_container) {}
828class ReissnerBeamElasticLProperty :
public ReissnerBeamConstantCrossSectionElasticProperty<T> {
831 const T& E,
const T& p,
const T& density,
const T& nsmass,
const RTable& rtable,
832 const RTable& frtable) {
833 BeamCrossSectionL<T> section;
834 section.load(rtable);
835 this->shear_center[0] = -section.yc;
836 this->shear_center[1] = -section.zc;
837 const T G = E / (2 * (1 + p));
838 this->C[0] = G * section.A * section.K1;
839 this->C[1] = G * section.A * section.K2;
840 this->C[2] = E * section.A;
841 this->C[3] = E * section.Iyy;
842 this->C[4] = E * section.Izz;
843 this->C[5] = G * section.It;
845 this->C[7] = E * section.Iyz;
846 this->mass = density * section.A;
847 this->ns_mass = nsmass;
848 this->inertia_moment[0] = density * section.Iyy;
849 this->inertia_moment[1] = density * section.Izz;
850 this->inertia_moment[2] = 0;
851 this->area = section.A;
855 const T* get_C()
const {
return &this->C[0]; }
858 const T reference_to_undeformed_cross_section_rotator[3][3],
859 const T undeformed_to_deformed_cross_section_rotator[3][3],
860 const T strain_and_curvature[6], GradientContainer* gradient_container) {}
869 const T& E,
const T& p,
const T& density,
const T& nsmass,
const RTable& rtable,
871 BeamCrossSectionI<T> section;
872 section.load(rtable);
897 const T G = E / (2 * (1 + p));
898 this->C[0] = G * section.A * section.K1;
899 this->C[1] = G * section.A * section.K2;
900 this->C[2] = E * section.A;
901 this->C[3] = E * section.Iyy;
902 this->C[4] = E * section.Izz;
903 this->C[5] = G * section.It;
906 this->mass = density * section.A;
907 this->ns_mass = nsmass;
908 this->inertia_moment[0] = density * section.Iyy;
909 this->inertia_moment[1] = density * section.Izz;
910 this->inertia_moment[2] = 0;
911 this->area = section.A;
915 const T* get_C()
const {
return &this->C[0]; }
924 const T& E,
const T& p,
const T& density,
const T& nsmass,
const RTable& rtable,
926 BeamCrossSectionC<T> section;
927 section.load(rtable);
928 this->shear_center[0] = section.ys - section.yc;
929 this->shear_center[1] = section.zs - section.zc;
930 this->neutral_axis_point[0] = 0;
931 this->neutral_axis_point[1] = 0;
933 const T G = E / (2 * (1 + p));
934 this->C[0] = G * section.A * section.K1;
935 this->C[1] = G * section.A * section.K2;
936 this->C[2] = E * section.A;
937 this->C[3] = E * section.Iyy;
938 this->C[4] = E * section.Izz;
939 this->C[5] = G * section.It;
942 this->mass = density * section.A;
943 this->ns_mass = nsmass;
944 this->inertia_moment[0] = density * section.Iyy;
945 this->inertia_moment[1] = density * section.Izz;
946 this->inertia_moment[2] = 0;
947 this->area = section.A;
951 const T* get_C()
const {
return &this->C[0]; }
954 const T reference_to_undeformed_cross_section_rotator[3][3],
955 const T undeformed_to_deformed_cross_section_rotator[3][3],
960class ReissnerBeamElasticRodProperty :
public ReissnerBeamConstantCrossSectionElasticProperty<T> {
963 const T& E,
const T& p,
const T& density,
const T& nsmass,
const RTable& rtable,
965 const T G = E / (2 * (1 + p));
968 BeamCrossSectionRod<T> section;
969 section.load(rtable);
970 this->C[0] = G * section.A * section.K1;
971 this->C[1] = G * section.A * section.K2;
972 this->C[2] = E * section.A;
973 this->C[3] = E * section.Iyy;
974 this->C[4] = E * section.Izz;
975 this->C[5] = G * section.It;
978 this->mass = density * section.A;
979 this->ns_mass = nsmass;
980 this->inertia_moment[0] = density * section.Iyy;
981 this->inertia_moment[1] = density * section.Izz;
982 this->inertia_moment[2] = 0;
983 this->area = section.A;
987 const T* get_C()
const {
return &this->C[0]; }
990 const T reference_to_undeformed_cross_section_rotator[3][3],
991 const T undeformed_to_deformed_cross_section_rotator[3][3],
992 const T strain_and_curvature[6], GradientContainer* gradient_container) {}
996class ReissnerBeamConstantCrossSectionElasticFEMProperty :
public ReissnerBeamProperty<T> {
998 ReissnerBeamConstantCrossSectionElasticFEMProperty(Model* m)
999 : cs_model(m), mass(0), ns_mass(0), compute_gradients(false) {
1000 std::fill_n(neutral_point, 2, T(0));
1001 std::fill_n(inertia_point, 2, T(0));
1002 std::fill_n(inertia_moment, 3, T(0));
1003 std::fill_n(ns_inertia_point, 2, T(0));
1004 std::fill_n(constant_force_and_moment, 6, T(0));
1007 ReissnerBeamConstantCrossSectionElasticFEMProperty()
1008 : cs_model(nullptr), mass(0), ns_mass(0), compute_gradients(false) {
1009 std::fill_n(neutral_point, 2, T(0));
1010 std::fill_n(inertia_point, 2, T(0));
1011 std::fill_n(inertia_moment, 3, T(0));
1012 std::fill_n(ns_inertia_point, 2, T(0));
1013 std::fill_n(constant_force_and_moment, 6, T(0));
1016 ~ReissnerBeamConstantCrossSectionElasticFEMProperty() {
delete cs_model; }
1018 bool get_nodes_neutral_point(
1019 int nb_nodes,
const T node_coor[][3],
const T node_icoor[],
const T node_e3[][3],
1020 T neutral_point_[][2]) {
1021 for (
int k = 0; k != nb_nodes; ++k) {
1022 neutral_point_[k][0] = neutral_point[0];
1023 neutral_point_[k][1] = neutral_point[1];
1029 Model& model,
const bool linear,
const EquilibriumSolution equilibrium_solution,
1030 const double time,
const double delta_time, GradientContainer* gradient_container,
1031 SolverHints* solver_hints,
const Element& element,
const double element_coordinate,
1032 const b2linalg::Vector<double, b2linalg::Vdense_constref> nodes_interpolation,
1033 const T reference_to_undeformed_cross_section_rotator[3][3],
1034 const T undeformed_to_deformed_cross_section_rotator[3][3],
1035 const T strain_and_curvature[6],
const T acceleration[6],
1036 const ReissnerBeamPropertyBase::Components components, T force_and_moment[6],
1037 T d_force_and_moment_d_strain_and_curvature[6][6], T d_force_and_moment_d_time[6],
1038 T inertia[6], T d_inertia_d_acceleration[3][3][3]) {
1039 if (force_and_moment) {
1040 if (strain_and_curvature) {
1041 if (components == this->only_membrane_and_shear_components
1042 || components == this->all_components) {
1043 for (
int i = 0; i != 3; ++i) {
1045 for (
int j = 0; j != 3; ++j) {
1046 tmp += lambda(i, j) * strain_and_curvature[j];
1048 force_and_moment[i] = tmp;
1051 std::fill(force_and_moment, force_and_moment + 3, T(0));
1053 if (components != this->only_membrane_and_shear_components) {
1054 for (
int i = 0; i != 3; ++i) {
1056 for (
int j = 3; j != 6; ++j) {
1057 tmp += lambda(i, j) * strain_and_curvature[j];
1059 force_and_moment[i] += tmp;
1061 for (
int i = 3; i != 6; ++i) {
1063 for (
int j = 0; j != 6; ++j) {
1064 tmp += lambda(i, j) * strain_and_curvature[j];
1066 force_and_moment[i] = tmp;
1069 std::fill(force_and_moment + 3, force_and_moment + 6, T(0));
1072 std::fill(force_and_moment, force_and_moment + 6, T(0));
1074 if (components != this->only_membrane_and_shear_components) {
1075 for (
int i = 0; i != 6; ++i) {
1076 force_and_moment[i] += constant_force_and_moment[i];
1081 if (d_force_and_moment_d_strain_and_curvature) {
1082 if (components == this->all_components) {
1084 &lambda(0, 0), &lambda(0, 7), d_force_and_moment_d_strain_and_curvature[0]);
1087 d_force_and_moment_d_strain_and_curvature[0],
1088 d_force_and_moment_d_strain_and_curvature[6], T(0));
1089 if (components == this->only_membrane_and_shear_components) {
1090 for (
int j = 0; j != 3; ++j) {
1091 for (
int i = 0; i != 3; ++i) {
1092 d_force_and_moment_d_strain_and_curvature[j][i] = lambda(i, j);
1095 }
else if (components != this->only_membrane_and_shear_components) {
1096 for (
int j = 0; j != 3; ++j) {
1097 for (
int i = 3; i != 6; ++i) {
1098 d_force_and_moment_d_strain_and_curvature[j][i] = lambda(i, j);
1101 for (
int j = 3; j != 6; ++j) {
1102 for (
int i = 0; i != 6; ++i) {
1103 d_force_and_moment_d_strain_and_curvature[j][i] = lambda(i, j);
1110 const bool inertia_point_zero = inertia_point[0] == 0 && inertia_point[1] == 0;
1111 const bool ns_inertia_point_zero = ns_inertia_point[0] == 0 && ns_inertia_point[1] == 0;
1114 if (inertia_point_zero) {
1115 for (
int i = 0; i != 3; ++i) { inertia[i] = mass * acceleration[i]; }
1116 for (
int i = 0; i != 2; ++i) {
1117 inertia[i + 3] = inertia_moment[i] * acceleration[i + 3];
1119 inertia[5] = (inertia_moment[0] + inertia_moment[1]) * acceleration[5];
1120 inertia[3] += inertia_moment[2] * acceleration[4];
1121 inertia[4] += inertia_moment[2] * acceleration[3];
1123 inertia[0] = mass * (acceleration[0] - inertia_point[1] * acceleration[5]);
1124 inertia[1] = mass * (acceleration[1] + inertia_point[0] * acceleration[5]);
1126 * (acceleration[2] + inertia_point[1] * acceleration[3]
1127 - inertia_point[0] * acceleration[4]);
1128 inertia[3] = inertia_moment[0] * acceleration[3]
1129 + inertia_moment[2] * acceleration[4]
1130 + inertia[2] * inertia_point[1];
1131 inertia[4] = inertia_moment[1] * acceleration[4]
1132 + inertia_moment[2] * acceleration[3]
1133 - inertia[2] * inertia_point[0];
1134 inertia[5] = (inertia_moment[0] + inertia_moment[1]) * acceleration[5]
1135 - inertia[0] * inertia_point[1] + inertia[1] * inertia_point[1];
1137 if (ns_inertia_point_zero) {
1138 for (
int i = 0; i != 3; ++i) { inertia[i] += ns_mass * acceleration[i]; }
1141 ns_mass * (acceleration[0] - ns_inertia_point[1] * acceleration[5]);
1144 ns_mass * (acceleration[1] + ns_inertia_point[0] * acceleration[5]);
1146 const T i2 = ns_mass
1147 * (acceleration[2] + ns_inertia_point[1] * acceleration[3]
1148 - ns_inertia_point[0] * acceleration[4]);
1150 inertia[3] += i2 * ns_inertia_point[1];
1151 inertia[4] += -i2 * ns_inertia_point[0];
1152 inertia[5] += -i0 * ns_inertia_point[1] + i1 * ns_inertia_point[1];
1155 std::fill(inertia, inertia + 6, T(0));
1159 if (d_inertia_d_acceleration) {
1160 std::fill(d_inertia_d_acceleration[0][0], d_inertia_d_acceleration[3][0], T(0));
1161 for (
int i = 0; i != 3; ++i) { d_inertia_d_acceleration[0][i][i] = mass + ns_mass; }
1162 for (
int i = 0; i != 2; ++i) { d_inertia_d_acceleration[2][i][i] = inertia_moment[i]; }
1163 d_inertia_d_acceleration[2][2][2] = inertia_moment[0] + inertia_moment[1];
1164 d_inertia_d_acceleration[2][1][0] = inertia_moment[2];
1165 if (!inertia_point_zero) {
1166 d_inertia_d_acceleration[1][0][2] =
1167 mass * inertia_point[1] + ns_mass * ns_inertia_point[1];
1168 d_inertia_d_acceleration[1][1][2] =
1169 -mass * inertia_point[0] - ns_mass * ns_inertia_point[0];
1170 d_inertia_d_acceleration[1][2][0] =
1171 -mass * inertia_point[1] - ns_mass * ns_inertia_point[1];
1172 d_inertia_d_acceleration[1][2][1] =
1173 mass * inertia_point[0] + ns_mass * ns_inertia_point[0];
1174 d_inertia_d_acceleration[2][0][0] +=
1175 mass * inertia_point[1] * inertia_point[1]
1176 + ns_mass * ns_inertia_point[1] * ns_inertia_point[1];
1177 d_inertia_d_acceleration[2][1][0] +=
1178 -mass * inertia_point[0] * inertia_point[1]
1179 - -ns_mass * ns_inertia_point[0] * ns_inertia_point[1];
1180 d_inertia_d_acceleration[2][1][1] +=
1181 mass * inertia_point[0] * inertia_point[0]
1182 + ns_mass * ns_inertia_point[0] * ns_inertia_point[0];
1183 d_inertia_d_acceleration[2][2][2] +=
1185 * (inertia_point[0] * inertia_point[0]
1186 + inertia_point[1] * inertia_point[1])
1188 * (ns_inertia_point[0] * ns_inertia_point[0]
1189 + ns_inertia_point[1] * ns_inertia_point[1]);
1191 d_inertia_d_acceleration[2][0][1] = d_inertia_d_acceleration[2][1][0];
1194 if (d_force_and_moment_d_time) {
1195 std::fill(d_force_and_moment_d_time, d_force_and_moment_d_time + 6, T(0));
1198 if (gradient_container && compute_gradients
1199 && components == this->only_membrane_and_shear_components) {
1201 std::copy(constant_force_and_moment, constant_force_and_moment + 6, force_moment);
1202 static const int index[6] = {1, 2, 0, 4, 5, 3};
1203 for (
int i = 0; i != 6; ++i) {
1204 const int ii = index[i];
1205 for (
int j = 0; j != 6; ++j) {
1206 force_moment[ii] += lambda(i, j) * strain_and_curvature[j];
1210 static const GradientContainer::FieldDescription force_beam_descr = {
1211 "SECTION_FORCES",
"Fx.Fy.Fz",
"Section forces", 3, 3, 1, 3,
false,
typeid(T)};
1212 if (gradient_container->compute_field_value(force_beam_descr.name)) {
1213 gradient_container->set_field_value(force_beam_descr, force_moment);
1215 static const GradientContainer::FieldDescription moment_beam_descr = {
1216 "SECTION_MOMENTS",
"Mx.My.dM",
"Secction moments", 3, 3, 1, 3,
false,
typeid(T)};
1217 if (gradient_container->compute_field_value(moment_beam_descr.name)) {
1218 gradient_container->set_field_value(moment_beam_descr, force_moment + 3);
1221 static const GradientContainer::FieldDescription coor_descr = {
1222 "COOR_IP",
"x.y.z",
"Coordinates", 3, 3, 1, 3,
false,
typeid(T)};
1223 static const GradientContainer::FieldDescription disp_descr = {
1224 "DISP_IP",
"dx.dy.dz",
"Displacements", 3, 3, 1, 3,
false,
typeid(T)};
1226 const T covariant_base[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
1227 MaxGradientContainer l_gradient_container;
1228 for (
typename cs_properties_t::iterator p = cs_properties.begin();
1229 p != cs_properties.end(); ++p) {
1230 for (std::vector<Node*>::iterator n = p->second.begin(); n != p->second.end();
1232 const size_t nid = (*n)->get_id();
1235 std::copy(&strain[6](0, nid), &strain[6](0, nid) + 2, stra);
1236 std::copy(&stress[6](0, nid), &stress[6](0, nid) + 2, stre);
1237 for (
int i = 0; i != 6; ++i) {
1238 for (
int j = 0; j != 6; ++j) {
1239 stra[j] += force_moment[i] * strain[i](j, nid);
1242 for (
int i = 0; i != 6; ++i) {
1243 stre[0] += force_moment[i] * stress[i](0, nid);
1244 stre[3] += force_moment[i] * stress[i](1, nid);
1245 stre[5] += force_moment[i] * stress[i](2, nid);
1247 const_cast<SolidMechanics3D<T>*
>(p->first)
1248 ->get_static_linear_cross_section_gradient(
1249 covariant_base, stra, stre, &l_gradient_container);
1250 if (l_gradient_container.is_last_max()) {
1251 std::pair<int, const T*> coor = (*n)->get_coor<T>();
1252 const GradientContainer::InternalElementPosition ip = {
1253 element_coordinate, coor.second[0], coor.second[1], 1};
1254 l_gradient_container.set_current_position(ip);
1255 l_gradient_container.set_strain_and_stress(stra, stre);
1259 l_gradient_container.set_gradient(gradient_container);
1263 void field_section_integration(
1264 const T element_coordinate,
const T value[6],
const bool multiply_with_density,
1266 if (multiply_with_density) {
1268 force[0] = mass * (value[0] - inertia_point[1] * value[5]);
1269 force[1] = mass * (value[1] + inertia_point[0] * value[5]);
1271 mass * (value[2] + inertia_point[1] * value[3] - inertia_point[0] * value[4]);
1272 force[3] = inertia_moment[0] * value[3] + inertia_moment[2] * value[4]
1273 + force[2] * inertia_point[1];
1274 force[4] = inertia_moment[1] * value[4] + inertia_moment[2] * value[3]
1275 - value[2] * inertia_point[0];
1276 force[5] = (inertia_moment[0] + inertia_moment[1]) * value[5]
1277 - force[0] * inertia_point[1] + force[1] * inertia_point[1];
1280 const T i0 = ns_mass * (value[0] - ns_inertia_point[1] * value[5]);
1282 const T i1 = ns_mass * (value[1] + ns_inertia_point[0] * value[5]);
1286 * (value[2] + ns_inertia_point[1] * value[3] - ns_inertia_point[0] * value[4]);
1288 force[3] += i2 * ns_inertia_point[1];
1289 force[4] += -i2 * ns_inertia_point[0];
1290 force[5] += -i0 * ns_inertia_point[1] + i1 * ns_inertia_point[1];
1297 void set_pre_stress(
const T& force,
const T coor[2]) {
1298 constant_force_and_moment[2] += force;
1300 constant_force_and_moment[0] += coor[1] * force;
1301 constant_force_and_moment[1] += coor[0] * force;
1305 void set_pre_stress(
const T force[3]) {
1306 constant_force_and_moment[2] += force[0];
1307 constant_force_and_moment[0] += force[1];
1308 constant_force_and_moment[1] += force[2];
1311 b2linalg::Matrix<T> lambda;
1312 T constant_force_and_moment[6];
1313 b2linalg::Matrix<T> v[7];
1314 b2linalg::Matrix<T> strain[7];
1315 b2linalg::Matrix<T> stress[7];
1317 typedef std::vector<std::pair<const SolidMechanics3D<T>*, std::vector<Node*> > >
1319 cs_properties_t cs_properties;
1324 T inertia_moment[3];
1325 T ns_inertia_point[2];
1327 bool compute_gradients;
1329 class MaxGradientContainer :
public GradientContainer {
1331 MaxGradientContainer() : last_is_a_maximum(false), descr_ptr(nullptr) {
1332 buffer[1] = std::numeric_limits<T>::lowest();
1335 bool is_last_max()
const {
return last_is_a_maximum; }
1337 bool set_current_element(
const Element& e)
override {
1342 void set_gradient(GradientContainer* gradient) {
1371 void set_current_position(
1372 const InternalElementPosition& pos,
const double volume = T(0))
override {
1376 void set_current_volume(
const double volume)
override {}
1378 void set_strain_and_stress(
const T _strain[6],
const T _stress[6]) {
1379 std::copy(_strain, _strain + 6, strain);
1380 std::copy(_stress, _stress + 6, stress);
1385 if (value[1] > buffer[1]) {
1387 std::copy(value, value + descr.nb_comp, buffer);
1388 last_is_a_maximum =
true;
1390 last_is_a_maximum =
false;
1394 bool compute_field_value(
const std::string& name)
const override {
return true; }
1397 bool last_is_a_maximum;
1398 const FieldDescription* descr_ptr;
1399 InternalElementPosition ip;
#define THROW
Definition b2exception.H:198
Definition b2solution.H:54
virtual void set_field_value(const FieldDescription &descr, const int *value)
Definition b2solution.H:146
Definition b2rtable.H:427
Definition b2reissner_beam_property.H:921
Definition b2reissner_beam_property.H:866
Contains the base classes for implementing Finite Elements.
Definition b2boundary_condition.H:32
GenericException< UnimplementedError_name > UnimplementedError
Definition b2exception.H:314