|
7 | 7 |
|
8 | 8 | #include "4C_solid_3D_ele_line.hpp" |
9 | 9 |
|
| 10 | +#include "4C_fem_discretization.hpp" |
| 11 | +#include "4C_fem_general_cell_type_traits.hpp" |
| 12 | +#include "4C_fem_general_extract_values.hpp" |
| 13 | +#include "4C_legacy_enum_definitions_element_actions.hpp" |
10 | 14 | #include "4C_linalg_serialdensematrix.hpp" |
| 15 | +#include "4C_linalg_tensor.hpp" |
11 | 16 | #include "4C_solid_3D_ele_neumann_evaluator.hpp" |
12 | 17 | #include "4C_utils_exceptions.hpp" |
13 | 18 |
|
|
19 | 24 | FOUR_C_NAMESPACE_OPEN |
20 | 25 |
|
21 | 26 |
|
| 27 | +namespace |
| 28 | +{ |
| 29 | + template <Core::FE::CellType celltype, unsigned dim> |
| 30 | + std::array<Core::LinAlg::Tensor<double, dim>, Core::FE::num_nodes(celltype)> |
| 31 | + evaluate_current_coordinates(const Core::Elements::Element& ele, |
| 32 | + const Core::FE::Discretization& discretization, const std::vector<int>& lm) |
| 33 | + { |
| 34 | + constexpr unsigned num_dofs = dim * Core::FE::num_nodes(celltype); |
| 35 | + std::array<double, num_dofs> mydisp = |
| 36 | + Core::FE::extract_values_as_array<num_dofs>(*discretization.get_state("displacement"), lm); |
| 37 | + |
| 38 | + std::array<Core::LinAlg::Tensor<double, dim>, Core::FE::num_nodes(celltype)> |
| 39 | + current_nodal_coordinates; |
| 40 | + |
| 41 | + for (int i = 0; i < Core::FE::num_nodes(celltype); ++i) |
| 42 | + { |
| 43 | + for (std::size_t d = 0; d < dim; ++d) |
| 44 | + { |
| 45 | + current_nodal_coordinates[i](d) = ele.nodes()[i]->x()[d] + mydisp[i * dim + d]; |
| 46 | + } |
| 47 | + } |
| 48 | + |
| 49 | + return current_nodal_coordinates; |
| 50 | + } |
| 51 | +} // namespace |
| 52 | + |
22 | 53 | template <unsigned dim> |
23 | 54 | Discret::Elements::SolidLineType<dim> Discret::Elements::SolidLineType<dim>::instance_; |
24 | 55 |
|
@@ -107,12 +138,92 @@ void Discret::Elements::SolidLine<dim>::print(std::ostream& os) const |
107 | 138 | Element::print(os); |
108 | 139 | } |
109 | 140 |
|
| 141 | +template <unsigned dim> |
| 142 | +int Discret::Elements::SolidLine<dim>::evaluate(Teuchos::ParameterList& params, |
| 143 | + Core::FE::Discretization& discretization, std::vector<int>& lm, |
| 144 | + Core::LinAlg::SerialDenseMatrix& elematrix1, Core::LinAlg::SerialDenseMatrix& elematrix2, |
| 145 | + Core::LinAlg::SerialDenseVector& elevector1, Core::LinAlg::SerialDenseVector& elevector2, |
| 146 | + Core::LinAlg::SerialDenseVector& elevector3) |
| 147 | +{ |
| 148 | + set_params_interface_ptr(params); |
| 149 | + |
| 150 | + Core::Elements::ActionType act = |
| 151 | + Core::Elements::string_to_action_type(params.get<std::string>("action")); |
| 152 | + |
| 153 | + switch (act) |
| 154 | + { |
| 155 | + case Core::Elements::ActionType::calc_struct_constrarea: |
| 156 | + { |
| 157 | + FOUR_C_ASSERT_ALWAYS( |
| 158 | + shape() == Core::FE::CellType::line2, "Area Constraint only works for line2 elements!"); |
| 159 | + |
| 160 | + constexpr Core::FE::CellType celltype = Core::FE::CellType::line2; |
| 161 | + |
| 162 | + |
| 163 | + // We are not interested in volume of ghosted elements |
| 164 | + if (Core::Communication::my_mpi_rank(discretization.get_comm()) != owner()) return 0; |
| 165 | + |
| 166 | + auto current_nodal_coordinates = |
| 167 | + evaluate_current_coordinates<celltype, dim>(*this, discretization, lm); |
| 168 | + |
| 169 | + elevector3[0] = 0.5 * (current_nodal_coordinates[0](1) + current_nodal_coordinates[1](1)) * |
| 170 | + (current_nodal_coordinates[1](0) - current_nodal_coordinates[0](0)); |
| 171 | + } |
| 172 | + break; |
| 173 | + case Core::Elements::ActionType::calc_struct_areaconstrstiff: |
| 174 | + { |
| 175 | + FOUR_C_ASSERT_ALWAYS( |
| 176 | + shape() == Core::FE::CellType::line2, "Area Constraint only works for line2 elements!"); |
| 177 | + |
| 178 | + constexpr Core::FE::CellType celltype = Core::FE::CellType::line2; |
| 179 | + |
| 180 | + // We are not interested in volume of ghosted elements |
| 181 | + if (Core::Communication::my_mpi_rank(discretization.get_comm()) != owner()) return 0; |
| 182 | + |
| 183 | + auto current_nodal_coordinates = |
| 184 | + evaluate_current_coordinates<celltype, dim>(*this, discretization, lm); |
| 185 | + |
| 186 | + FOUR_C_ASSERT(elevector1.length() == 4, |
| 187 | + "Expected elevector1 to have size 4 for line2 area constraint! Given vector has size {}", |
| 188 | + elevector1.length()); |
| 189 | + FOUR_C_ASSERT(elematrix1.num_cols() == 4 && elematrix1.num_rows() == 4, |
| 190 | + "Expected elematrix1 to have 4 rows and 4 columns for line2 area constraint! Given " |
| 191 | + "matrix has {} rows and {} columns", |
| 192 | + elematrix1.num_rows(), elematrix1.num_cols()); |
| 193 | + |
| 194 | + elevector1[0] = 0.5 * (current_nodal_coordinates[0](1) + current_nodal_coordinates[1](1)); |
| 195 | + elevector1[1] = 0.5 * (current_nodal_coordinates[0](0) - current_nodal_coordinates[1](0)); |
| 196 | + elevector1[2] = -0.5 * (current_nodal_coordinates[0](1) + current_nodal_coordinates[1](1)); |
| 197 | + elevector1[3] = 0.5 * (current_nodal_coordinates[0](0) - current_nodal_coordinates[1](0)); |
| 198 | + elevector2 = elevector1; |
| 199 | + |
| 200 | + elematrix1.put_scalar(0.0); |
| 201 | + elematrix1(0, 1) = 0.5; |
| 202 | + elematrix1(0, 3) = 0.5; |
| 203 | + elematrix1(1, 0) = 0.5; |
| 204 | + elematrix1(1, 2) = -0.5; |
| 205 | + elematrix1(2, 1) = -0.5; |
| 206 | + elematrix1(2, 3) = -0.5; |
| 207 | + elematrix1(3, 0) = 0.5; |
| 208 | + elematrix1(3, 2) = -0.5; |
| 209 | + |
| 210 | + elevector3[0] = 0.5 * (current_nodal_coordinates[0](1) + current_nodal_coordinates[1](1)) * |
| 211 | + (current_nodal_coordinates[1](0) - current_nodal_coordinates[0](0)); |
| 212 | + } |
| 213 | + break; |
| 214 | + default: |
| 215 | + FOUR_C_THROW("Unknown type of action {} for SolidLine element", action_type_to_string(act)); |
| 216 | + } |
| 217 | + return 0; |
| 218 | +} |
| 219 | + |
110 | 220 | template <unsigned dim> |
111 | 221 | int Discret::Elements::SolidLine<dim>::evaluate_neumann(Teuchos::ParameterList& params, |
112 | 222 | Core::FE::Discretization& discretization, const Core::Conditions::Condition& condition, |
113 | 223 | std::vector<int>& lm, Core::LinAlg::SerialDenseVector& elevec1, |
114 | 224 | Core::LinAlg::SerialDenseMatrix* elemat1) |
115 | 225 | { |
| 226 | + static_assert(dim == 2 || dim == 3, "SolidLine element only implemented for 2D and 3D!"); |
116 | 227 | set_params_interface_ptr(params); |
117 | 228 |
|
118 | 229 | const double total_time = std::invoke( |
|
0 commit comments