diff --git a/src/model/solid_mechanics/material.cc b/src/model/solid_mechanics/material.cc index 03d13e29b..95597443d 100644 --- a/src/model/solid_mechanics/material.cc +++ b/src/model/solid_mechanics/material.cc @@ -1,1632 +1,1632 @@ /** * @file material.cc * * @author Aurelia Isabel Cuba Ramos * @author Marco Vocialta * @author Nicolas Richart * @author Daniel Pino Muñoz * * @date creation: Tue Jul 27 2010 * @date last modification: Tue Sep 16 2014 * * @brief Implementation of the common part of the material class * * @section LICENSE * * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "material.hh" #include "solid_mechanics_model.hh" #include "sparse_matrix.hh" #include "dof_synchronizer.hh" /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ Material::Material(SolidMechanicsModel & model, const ID & id) : Memory(id, model.getMemoryID()), Parsable(_st_material, id), is_init(false), fem(&(model.getFEEngine())), finite_deformation(false), name(""), model(&model), spatial_dimension(this->model->getSpatialDimension()), element_filter("element_filter", id, this->memory_id), stress("stress", *this), eigengradu("eigen_grad_u", *this), gradu("grad_u", *this), green_strain("green_strain",*this), piola_kirchhoff_2("piola_kirchhoff_2", *this), // potential_energy_vector(false), potential_energy("potential_energy", *this), is_non_local(false), use_previous_stress(false), use_previous_gradu(false), interpolation_inverse_coordinates("interpolation inverse coordinates", *this), interpolation_points_matrices("interpolation points matrices", *this) { AKANTU_DEBUG_IN(); /// for each connectivity types allocate the element filer array of the material model.getMesh().initElementTypeMapArray(element_filter, - 1, - spatial_dimension, - false, - _ek_regular); + 1, + spatial_dimension, + false, + _ek_regular); this->initialize(); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ Material::Material(SolidMechanicsModel & model, UInt dim, const Mesh & mesh, FEEngine & fe_engine, const ID & id) : Memory(id, model.getMemoryID()), Parsable(_st_material, id), is_init(false), fem(&(model.getFEEngine())), finite_deformation(false), name(""), model(&model), spatial_dimension(dim), element_filter("element_filter", id, this->memory_id), stress("stress", *this, dim, fe_engine, this->element_filter), eigengradu("eigen_grad_u", *this, dim, fe_engine, this->element_filter), gradu("gradu", *this, dim, fe_engine, this->element_filter), green_strain("green_strain", *this, dim, fe_engine, this->element_filter), piola_kirchhoff_2("poila_kirchhoff_2", *this, dim, fe_engine, this->element_filter), potential_energy("potential_energy", *this, dim, fe_engine, this->element_filter), is_non_local(false), use_previous_stress(false), use_previous_gradu(false), interpolation_inverse_coordinates("interpolation inverse_coordinates", *this, dim, fe_engine, this->element_filter), interpolation_points_matrices("interpolation points matrices", *this, dim, fe_engine, this->element_filter) { AKANTU_DEBUG_IN(); mesh.initElementTypeMapArray(element_filter, 1, spatial_dimension, false, _ek_regular); this->initialize(); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ Material::~Material() { AKANTU_DEBUG_IN(); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void Material::initialize() { registerParam("rho" , rho , Real(0.) , _pat_parsable | _pat_modifiable, "Density"); registerParam("name" , name , std::string(), _pat_parsable | _pat_readable); registerParam("finite_deformation" , finite_deformation , false , _pat_parsable | _pat_readable, "Is finite deformation"); registerParam("inelastic_deformation", inelastic_deformation, false , _pat_internal, "Is inelastic deformation"); /// allocate gradu stress for local elements eigengradu.initialize(spatial_dimension * spatial_dimension); gradu.initialize(spatial_dimension * spatial_dimension); stress.initialize(spatial_dimension * spatial_dimension); this->model->registerEventHandler(*this); } /* -------------------------------------------------------------------------- */ void Material::initMaterial() { AKANTU_DEBUG_IN(); if(finite_deformation) { this->piola_kirchhoff_2.initialize(spatial_dimension * spatial_dimension); if(use_previous_stress) this->piola_kirchhoff_2.initializeHistory(); this->green_strain.initialize(spatial_dimension * spatial_dimension); } if(use_previous_stress) this->stress.initializeHistory(); if(use_previous_gradu) this->gradu.initializeHistory(); for (std::map *>::iterator it = internal_vectors_real.begin(); it != internal_vectors_real.end(); ++it) it->second->resize(); for (std::map *>::iterator it = internal_vectors_uint.begin(); it != internal_vectors_uint.end(); ++it) it->second->resize(); for (std::map *>::iterator it = internal_vectors_bool.begin(); it != internal_vectors_bool.end(); ++it) it->second->resize(); is_init = true; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void Material::savePreviousState() { AKANTU_DEBUG_IN(); for (std::map *>::iterator it = internal_vectors_real.begin(); it != internal_vectors_real.end(); ++it) { if(it->second->hasHistory()) it->second->saveCurrentValues(); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ /** * Compute the residual by assembling @f$\int_{e} \sigma_e \frac{\partial * \varphi}{\partial X} dX @f$ * * @param[in] displacements nodes displacements * @param[in] ghost_type compute the residual for _ghost or _not_ghost element */ void Material::updateResidual(GhostType ghost_type) { AKANTU_DEBUG_IN(); computeAllStresses(ghost_type); assembleResidual(ghost_type); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void Material::assembleResidual(GhostType ghost_type) { AKANTU_DEBUG_IN(); UInt spatial_dimension = model->getSpatialDimension(); if(!finite_deformation){ Array & residual = const_cast &>(model->getResidual()); Mesh & mesh = fem->getMesh(); Mesh::type_iterator it = element_filter.firstType(spatial_dimension, ghost_type); Mesh::type_iterator last_type = element_filter.lastType(spatial_dimension, ghost_type); for(; it != last_type; ++it) { Array & elem_filter = element_filter(*it, ghost_type); UInt nb_element = elem_filter.getSize(); if (nb_element) { - const Array & shapes_derivatives = fem->getShapesDerivatives(*it, ghost_type); + const Array & shapes_derivatives = fem->getShapesDerivatives(*it, ghost_type); - UInt size_of_shapes_derivatives = shapes_derivatives.getNbComponent(); - UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it); - UInt nb_quadrature_points = fem->getNbQuadraturePoints(*it, ghost_type); + UInt size_of_shapes_derivatives = shapes_derivatives.getNbComponent(); + UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it); + UInt nb_quadrature_points = fem->getNbQuadraturePoints(*it, ghost_type); - /// compute @f$\sigma \frac{\partial \varphi}{\partial X}@f$ by @f$\mathbf{B}^t \mathbf{\sigma}_q@f$ - Array * sigma_dphi_dx = - new Array(nb_element*nb_quadrature_points, - size_of_shapes_derivatives, "sigma_x_dphi_/_dX"); + /// compute @f$\sigma \frac{\partial \varphi}{\partial X}@f$ by @f$\mathbf{B}^t \mathbf{\sigma}_q@f$ + Array * sigma_dphi_dx = + new Array(nb_element*nb_quadrature_points, + size_of_shapes_derivatives, "sigma_x_dphi_/_dX"); - Array * shapesd_filtered = - new Array(0, size_of_shapes_derivatives, "filtered shapesd"); + Array * shapesd_filtered = + new Array(0, size_of_shapes_derivatives, "filtered shapesd"); - FEEngine::filterElementalData(mesh, shapes_derivatives, *shapesd_filtered, - *it, ghost_type, elem_filter); + FEEngine::filterElementalData(mesh, shapes_derivatives, *shapesd_filtered, + *it, ghost_type, elem_filter); - Array & stress_vect = this->stress(*it, ghost_type); + Array & stress_vect = this->stress(*it, ghost_type); - Array::matrix_iterator sigma = - stress_vect.begin(spatial_dimension, spatial_dimension); - Array::matrix_iterator B = - shapesd_filtered->begin(spatial_dimension, nb_nodes_per_element); - Array::matrix_iterator Bt_sigma_it = - sigma_dphi_dx->begin(spatial_dimension, nb_nodes_per_element); + Array::matrix_iterator sigma = + stress_vect.begin(spatial_dimension, spatial_dimension); + Array::matrix_iterator B = + shapesd_filtered->begin(spatial_dimension, nb_nodes_per_element); + Array::matrix_iterator Bt_sigma_it = + sigma_dphi_dx->begin(spatial_dimension, nb_nodes_per_element); - for (UInt q = 0; q < nb_element*nb_quadrature_points; ++q, ++sigma, ++B, ++Bt_sigma_it) - Bt_sigma_it->mul(*sigma, *B); + for (UInt q = 0; q < nb_element*nb_quadrature_points; ++q, ++sigma, ++B, ++Bt_sigma_it) + Bt_sigma_it->mul(*sigma, *B); - delete shapesd_filtered; + delete shapesd_filtered; - /** - * compute @f$\int \sigma * \frac{\partial \varphi}{\partial X}dX@f$ by @f$ \sum_q \mathbf{B}^t - * \mathbf{\sigma}_q \overline w_q J_q@f$ - */ - Array * int_sigma_dphi_dx = new Array(nb_element, - nb_nodes_per_element * spatial_dimension, - "int_sigma_x_dphi_/_dX"); + /** + * compute @f$\int \sigma * \frac{\partial \varphi}{\partial X}dX@f$ by @f$ \sum_q \mathbf{B}^t + * \mathbf{\sigma}_q \overline w_q J_q@f$ + */ + Array * int_sigma_dphi_dx = new Array(nb_element, + nb_nodes_per_element * spatial_dimension, + "int_sigma_x_dphi_/_dX"); - fem->integrate(*sigma_dphi_dx, *int_sigma_dphi_dx, - size_of_shapes_derivatives, - *it, ghost_type, - elem_filter); - delete sigma_dphi_dx; + fem->integrate(*sigma_dphi_dx, *int_sigma_dphi_dx, + size_of_shapes_derivatives, + *it, ghost_type, + elem_filter); + delete sigma_dphi_dx; - /// assemble - fem->assembleArray(*int_sigma_dphi_dx, residual, - model->getDOFSynchronizer().getLocalDOFEquationNumbers(), - residual.getNbComponent(), - *it, ghost_type, elem_filter, -1); - delete int_sigma_dphi_dx; + /// assemble + fem->assembleArray(*int_sigma_dphi_dx, residual, + model->getDOFSynchronizer().getLocalDOFEquationNumbers(), + residual.getNbComponent(), + *it, ghost_type, elem_filter, -1); + delete int_sigma_dphi_dx; } } } else{ switch (spatial_dimension){ case 1: this->assembleResidual<1>(ghost_type); break; case 2: this->assembleResidual<2>(ghost_type); break; case 3: this->assembleResidual<3>(ghost_type); break; } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ /** * Compute the stress from the gradu * * @param[in] current_position nodes postition + displacements * @param[in] ghost_type compute the residual for _ghost or _not_ghost element */ void Material::computeAllStresses(GhostType ghost_type) { AKANTU_DEBUG_IN(); UInt spatial_dimension = model->getSpatialDimension(); Mesh::type_iterator it = fem->getMesh().firstType(spatial_dimension, ghost_type); Mesh::type_iterator last_type = fem->getMesh().lastType(spatial_dimension, ghost_type); for(; it != last_type; ++it) { Array & elem_filter = element_filter(*it, ghost_type); if (elem_filter.getSize() == 0) continue; Array & gradu_vect = gradu(*it, ghost_type); /// compute @f$\nabla u@f$ fem->gradientOnQuadraturePoints(model->getDisplacement(), gradu_vect, - spatial_dimension, - *it, ghost_type, elem_filter); + spatial_dimension, + *it, ghost_type, elem_filter); gradu_vect -= eigengradu(*it, ghost_type); /// compute @f$\mathbf{\sigma}_q@f$ from @f$\nabla u@f$ computeStress(*it, ghost_type); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void Material::computeAllCauchyStresses(GhostType ghost_type) { AKANTU_DEBUG_IN(); AKANTU_DEBUG_ASSERT(finite_deformation,"The Cauchy stress can only be computed if you are working in finite deformation."); //resizeInternalArray(stress); Mesh::type_iterator it = fem->getMesh().firstType(spatial_dimension, ghost_type); Mesh::type_iterator last_type = fem->getMesh().lastType(spatial_dimension, ghost_type); for(; it != last_type; ++it) switch (spatial_dimension){ case 1: this->computeCauchyStress<1>(*it, ghost_type); break; case 2: this->computeCauchyStress<2>(*it, ghost_type); break; case 3: this->computeCauchyStress<3>(*it, ghost_type); break; } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ template void Material::computeCauchyStress(ElementType el_type, GhostType ghost_type) { AKANTU_DEBUG_IN(); Array::matrix_iterator gradu_it = this->gradu(el_type, ghost_type).begin(dim, dim); Array::matrix_iterator gradu_end = this->gradu(el_type, ghost_type).end(dim, dim); Array::matrix_iterator piola_it = this->piola_kirchhoff_2(el_type, ghost_type).begin(dim, dim); Array::matrix_iterator stress_it = this->stress(el_type, ghost_type).begin(dim, dim); Matrix F_tensor(dim, dim); for (; gradu_it != gradu_end; ++gradu_it, ++piola_it, ++stress_it) { Matrix & grad_u = *gradu_it; Matrix & piola = *piola_it; Matrix & sigma = *stress_it; gradUToF (grad_u, F_tensor); this->computeCauchyStressOnQuad(F_tensor, piola, sigma); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void Material::setToSteadyState(GhostType ghost_type) { AKANTU_DEBUG_IN(); const Array & displacement = model->getDisplacement(); //resizeInternalArray(gradu); UInt spatial_dimension = model->getSpatialDimension(); Mesh::type_iterator it = fem->getMesh().firstType(spatial_dimension, ghost_type); Mesh::type_iterator last_type = fem->getMesh().lastType(spatial_dimension, ghost_type); for(; it != last_type; ++it) { Array & elem_filter = element_filter(*it, ghost_type); Array & gradu_vect = gradu(*it, ghost_type); /// compute @f$\nabla u@f$ fem->gradientOnQuadraturePoints(displacement, gradu_vect, - spatial_dimension, - *it, ghost_type, elem_filter); + spatial_dimension, + *it, ghost_type, elem_filter); setToSteadyState(*it, ghost_type); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ /** * Compute the stiffness matrix by assembling @f$\int_{\omega} B^t \times D * \times B d\omega @f$ * * @param[in] current_position nodes postition + displacements * @param[in] ghost_type compute the residual for _ghost or _not_ghost element */ void Material::assembleStiffnessMatrix(GhostType ghost_type) { AKANTU_DEBUG_IN(); UInt spatial_dimension = model->getSpatialDimension(); Mesh::type_iterator it = element_filter.firstType(spatial_dimension, ghost_type); Mesh::type_iterator last_type = element_filter.lastType(spatial_dimension, ghost_type); for(; it != last_type; ++it) { if(finite_deformation){ switch (spatial_dimension) { case 1: - { - assembleStiffnessMatrixNL < 1 > (*it, ghost_type); - assembleStiffnessMatrixL2 < 1 > (*it, ghost_type); - break; - } + { + assembleStiffnessMatrixNL < 1 > (*it, ghost_type); + assembleStiffnessMatrixL2 < 1 > (*it, ghost_type); + break; + } case 2: - { - assembleStiffnessMatrixNL < 2 > (*it, ghost_type); - assembleStiffnessMatrixL2 < 2 > (*it, ghost_type); - break; - } + { + assembleStiffnessMatrixNL < 2 > (*it, ghost_type); + assembleStiffnessMatrixL2 < 2 > (*it, ghost_type); + break; + } case 3: - { - assembleStiffnessMatrixNL < 3 > (*it, ghost_type); - assembleStiffnessMatrixL2 < 3 > (*it, ghost_type); - break; - } + { + assembleStiffnessMatrixNL < 3 > (*it, ghost_type); + assembleStiffnessMatrixL2 < 3 > (*it, ghost_type); + break; + } } } else { switch(spatial_dimension) { case 1: { assembleStiffnessMatrix<1>(*it, ghost_type); break; } case 2: { assembleStiffnessMatrix<2>(*it, ghost_type); break; } case 3: { assembleStiffnessMatrix<3>(*it, ghost_type); break; } } } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ template void Material::assembleStiffnessMatrix(const ElementType & type, - GhostType ghost_type) { + GhostType ghost_type) { AKANTU_DEBUG_IN(); Array & elem_filter = element_filter(type, ghost_type); if (elem_filter.getSize()) { SparseMatrix & K = const_cast(model->getStiffnessMatrix()); const Array & shapes_derivatives = fem->getShapesDerivatives(type, - ghost_type); + ghost_type); Array & gradu_vect = gradu(type, ghost_type); UInt nb_element = elem_filter.getSize(); UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type); UInt nb_quadrature_points = fem->getNbQuadraturePoints(type, - ghost_type); + ghost_type); gradu_vect.resize(nb_quadrature_points * nb_element); fem->gradientOnQuadraturePoints(model->getDisplacement(), - gradu_vect, dim, type, ghost_type, - elem_filter); + gradu_vect, dim, type, ghost_type, + elem_filter); UInt tangent_size = getTangentStiffnessVoigtSize(dim); Array * tangent_stiffness_matrix = new Array(nb_element*nb_quadrature_points, tangent_size * tangent_size, - "tangent_stiffness_matrix"); + "tangent_stiffness_matrix"); tangent_stiffness_matrix->clear(); computeTangentModuli(type, *tangent_stiffness_matrix, ghost_type); Array * shapesd_filtered = new Array(0, dim * nb_nodes_per_element, "filtered shapesd"); FEEngine::filterElementalData(fem->getMesh(), shapes_derivatives, - *shapesd_filtered, type, ghost_type, elem_filter); + *shapesd_filtered, type, ghost_type, elem_filter); /// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$ UInt bt_d_b_size = dim * nb_nodes_per_element; Array * bt_d_b = new Array(nb_element * nb_quadrature_points, - bt_d_b_size * bt_d_b_size, - "B^t*D*B"); + bt_d_b_size * bt_d_b_size, + "B^t*D*B"); Matrix B(tangent_size, dim * nb_nodes_per_element); Matrix Bt_D(dim * nb_nodes_per_element, tangent_size); Array::matrix_iterator shapes_derivatives_filtered_it = shapesd_filtered->begin(dim, nb_nodes_per_element); Array::matrix_iterator Bt_D_B_it = bt_d_b->begin(dim*nb_nodes_per_element, dim*nb_nodes_per_element); Array::matrix_iterator D_it = tangent_stiffness_matrix->begin(tangent_size, tangent_size); Array::matrix_iterator D_end = tangent_stiffness_matrix->end (tangent_size, tangent_size); for(; D_it != D_end; ++D_it, ++Bt_D_B_it, ++shapes_derivatives_filtered_it) { Matrix & D = *D_it; Matrix & Bt_D_B = *Bt_D_B_it; VoigtHelper::transferBMatrixToSymVoigtBMatrix( - *shapes_derivatives_filtered_it, B, nb_nodes_per_element); + *shapes_derivatives_filtered_it, B, nb_nodes_per_element); Bt_D.mul(B, D); Bt_D_B.mul(Bt_D, B); } delete tangent_stiffness_matrix; delete shapesd_filtered; /// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$ Array * K_e = new Array(nb_element, - bt_d_b_size * bt_d_b_size, - "K_e"); + bt_d_b_size * bt_d_b_size, + "K_e"); fem->integrate(*bt_d_b, *K_e, - bt_d_b_size * bt_d_b_size, - type, ghost_type, - elem_filter); + bt_d_b_size * bt_d_b_size, + type, ghost_type, + elem_filter); delete bt_d_b; fem->assembleMatrix(*K_e, K, spatial_dimension, type, ghost_type, - elem_filter); + elem_filter); delete K_e; } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ template void Material::assembleStiffnessMatrixNL(const ElementType & type, - GhostType ghost_type) { + GhostType ghost_type) { AKANTU_DEBUG_IN(); SparseMatrix & K = const_cast (model->getStiffnessMatrix()); const Array & shapes_derivatives = fem->getShapesDerivatives(type, ghost_type); Array & elem_filter = element_filter(type, ghost_type); //Array & gradu_vect = delta_gradu(type, ghost_type); UInt nb_element = elem_filter.getSize(); UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type); UInt nb_quadrature_points = fem->getNbQuadraturePoints(type, ghost_type); //gradu_vect.resize(nb_quadrature_points * nb_element); // fem->gradientOnQuadraturePoints(model->getIncrement(), gradu_vect, // dim, type, ghost_type, &elem_filter); Array * shapes_derivatives_filtered = new Array (nb_element * nb_quadrature_points, - dim * nb_nodes_per_element, - "shapes derivatives filtered"); + dim * nb_nodes_per_element, + "shapes derivatives filtered"); Array::const_matrix_iterator shapes_derivatives_it = shapes_derivatives.begin(spatial_dimension, - nb_nodes_per_element); + nb_nodes_per_element); Array::matrix_iterator shapes_derivatives_filtered_it = shapes_derivatives_filtered->begin(spatial_dimension, - nb_nodes_per_element); + nb_nodes_per_element); UInt * elem_filter_val = elem_filter.storage(); for (UInt e = 0; e < nb_element; ++e, ++elem_filter_val) for (UInt q = 0; q < nb_quadrature_points; ++q, ++shapes_derivatives_filtered_it) *shapes_derivatives_filtered_it = shapes_derivatives_it[*elem_filter_val * nb_quadrature_points + q]; /// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$ UInt bt_s_b_size = dim * nb_nodes_per_element; Array * bt_s_b = new Array (nb_element * nb_quadrature_points, - bt_s_b_size * bt_s_b_size, - "B^t*D*B"); + bt_s_b_size * bt_s_b_size, + "B^t*D*B"); UInt piola_matrix_size = getCauchyStressMatrixSize(dim); Matrix B(piola_matrix_size, bt_s_b_size); Matrix Bt_S(bt_s_b_size, piola_matrix_size); Matrix S(piola_matrix_size, piola_matrix_size); shapes_derivatives_filtered_it = shapes_derivatives_filtered->begin(spatial_dimension, nb_nodes_per_element); Array::matrix_iterator Bt_S_B_it = bt_s_b->begin(bt_s_b_size, - bt_s_b_size); + bt_s_b_size); Array::matrix_iterator Bt_S_B_end = bt_s_b->end(bt_s_b_size, - bt_s_b_size); + bt_s_b_size); Array::matrix_iterator piola_it = piola_kirchhoff_2(type, ghost_type).begin(dim, dim); for (; Bt_S_B_it != Bt_S_B_end; ++Bt_S_B_it, ++shapes_derivatives_filtered_it, ++piola_it) { Matrix & Bt_S_B = *Bt_S_B_it; Matrix & Piola_kirchhoff_matrix = *piola_it; setCauchyStressMatrix< dim >(Piola_kirchhoff_matrix, S); VoigtHelper::transferBMatrixToBNL(*shapes_derivatives_filtered_it, B, nb_nodes_per_element); Bt_S.mul < true, false > (B, S); Bt_S_B.mul < false, false > (Bt_S, B); } delete shapes_derivatives_filtered; /// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$ Array * K_e = new Array (nb_element, - bt_s_b_size * bt_s_b_size, - "K_e"); + bt_s_b_size * bt_s_b_size, + "K_e"); fem->integrate(*bt_s_b, *K_e, - bt_s_b_size * bt_s_b_size, - type, ghost_type, - elem_filter); + bt_s_b_size * bt_s_b_size, + type, ghost_type, + elem_filter); delete bt_s_b; fem->assembleMatrix(*K_e, K, spatial_dimension, type, ghost_type, elem_filter); delete K_e; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ template void Material::assembleStiffnessMatrixL2(const ElementType & type, - GhostType ghost_type) { + GhostType ghost_type) { AKANTU_DEBUG_IN(); SparseMatrix & K = const_cast (model->getStiffnessMatrix()); const Array & shapes_derivatives = fem->getShapesDerivatives(type, ghost_type); Array & elem_filter = element_filter(type, ghost_type); Array & gradu_vect = gradu(type, ghost_type); UInt nb_element = elem_filter.getSize(); UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type); UInt nb_quadrature_points = fem->getNbQuadraturePoints(type, ghost_type); gradu_vect.resize(nb_quadrature_points * nb_element); fem->gradientOnQuadraturePoints(model->getDisplacement(), gradu_vect, - dim, type, ghost_type, elem_filter); + dim, type, ghost_type, elem_filter); UInt tangent_size = getTangentStiffnessVoigtSize(dim); Array * tangent_stiffness_matrix = new Array (nb_element*nb_quadrature_points, tangent_size * tangent_size, - "tangent_stiffness_matrix"); + "tangent_stiffness_matrix"); tangent_stiffness_matrix->clear(); computeTangentModuli(type, *tangent_stiffness_matrix, ghost_type); Array * shapes_derivatives_filtered = new Array (nb_element * nb_quadrature_points, - dim * nb_nodes_per_element, - "shapes derivatives filtered"); + dim * nb_nodes_per_element, + "shapes derivatives filtered"); Array::const_matrix_iterator shapes_derivatives_it = shapes_derivatives.begin(spatial_dimension, - nb_nodes_per_element); + nb_nodes_per_element); Array::matrix_iterator shapes_derivatives_filtered_it = shapes_derivatives_filtered->begin(spatial_dimension, - nb_nodes_per_element); + nb_nodes_per_element); UInt * elem_filter_val = elem_filter.storage(); for (UInt e = 0; e < nb_element; ++e, ++elem_filter_val) for (UInt q = 0; q < nb_quadrature_points; ++q, ++shapes_derivatives_filtered_it) *shapes_derivatives_filtered_it = shapes_derivatives_it[*elem_filter_val * nb_quadrature_points + q]; /// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$ UInt bt_d_b_size = dim * nb_nodes_per_element; Array * bt_d_b = new Array (nb_element * nb_quadrature_points, - bt_d_b_size * bt_d_b_size, - "B^t*D*B"); + bt_d_b_size * bt_d_b_size, + "B^t*D*B"); Matrix B(tangent_size, dim * nb_nodes_per_element); Matrix B2(tangent_size, dim * nb_nodes_per_element); Matrix Bt_D(dim * nb_nodes_per_element, tangent_size); shapes_derivatives_filtered_it = shapes_derivatives_filtered->begin(spatial_dimension, nb_nodes_per_element); Array::matrix_iterator Bt_D_B_it = bt_d_b->begin(dim*nb_nodes_per_element, - dim * nb_nodes_per_element); + dim * nb_nodes_per_element); Array::matrix_iterator grad_u_it = gradu_vect.begin(dim, dim); Array::matrix_iterator D_it = tangent_stiffness_matrix->begin(tangent_size, - tangent_size); + tangent_size); Array::matrix_iterator D_end = tangent_stiffness_matrix->end(tangent_size, - tangent_size); + tangent_size); for (; D_it != D_end; ++D_it, ++Bt_D_B_it, ++shapes_derivatives_filtered_it, ++grad_u_it) { Matrix & grad_u = *grad_u_it; Matrix & D = *D_it; Matrix & Bt_D_B = *Bt_D_B_it; //transferBMatrixToBL1 (*shapes_derivatives_filtered_it, B, nb_nodes_per_element); VoigtHelper::transferBMatrixToSymVoigtBMatrix(*shapes_derivatives_filtered_it, B, nb_nodes_per_element); VoigtHelper::transferBMatrixToBL2(*shapes_derivatives_filtered_it, grad_u, B2, nb_nodes_per_element); B += B2; Bt_D.mul < true, false > (B, D); Bt_D_B.mul < false, false > (Bt_D, B); } delete tangent_stiffness_matrix; delete shapes_derivatives_filtered; /// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$ Array * K_e = new Array (nb_element, - bt_d_b_size * bt_d_b_size, - "K_e"); + bt_d_b_size * bt_d_b_size, + "K_e"); fem->integrate(*bt_d_b, *K_e, - bt_d_b_size * bt_d_b_size, - type, ghost_type, - elem_filter); + bt_d_b_size * bt_d_b_size, + type, ghost_type, + elem_filter); delete bt_d_b; fem->assembleMatrix(*K_e, K, spatial_dimension, type, ghost_type, elem_filter); delete K_e; AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ template void Material::assembleResidual(GhostType ghost_type){ AKANTU_DEBUG_IN(); Array & residual = const_cast &> (model->getResidual()); Mesh & mesh = fem->getMesh(); Mesh::type_iterator it = element_filter.firstType(dim, ghost_type); Mesh::type_iterator last_type = element_filter.lastType(dim, ghost_type); for (; it != last_type; ++it) { const Array & shapes_derivatives = fem->getShapesDerivatives(*it, ghost_type); Array & elem_filter = element_filter(*it, ghost_type); if (elem_filter.getSize() == 0) continue; UInt size_of_shapes_derivatives = shapes_derivatives.getNbComponent(); UInt nb_element = elem_filter.getSize(); UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it); UInt nb_quadrature_points = fem->getNbQuadraturePoints(*it, ghost_type); Array * shapesd_filtered = new Array(0, size_of_shapes_derivatives, "filtered shapesd"); FEEngine::filterElementalData(mesh, shapes_derivatives, *shapesd_filtered, - *it, ghost_type, elem_filter); + *it, ghost_type, elem_filter); Array::matrix_iterator shapes_derivatives_filtered_it = shapesd_filtered->begin(dim, - nb_nodes_per_element); + nb_nodes_per_element); //Set stress vectors UInt stress_size = getTangentStiffnessVoigtSize(dim); //Set matrices B and BNL* UInt bt_s_size = dim * nb_nodes_per_element; Array * bt_s = new Array (nb_element * nb_quadrature_points, - bt_s_size, - "B^t*S"); + bt_s_size, + "B^t*S"); Array::matrix_iterator grad_u_it = this->gradu(*it, ghost_type).begin(dim, dim); Array::matrix_iterator grad_u_end = this->gradu(*it, ghost_type).end(dim, dim); Array::matrix_iterator stress_it = this->piola_kirchhoff_2(*it, ghost_type).begin(dim, dim); shapes_derivatives_filtered_it = shapesd_filtered->begin(dim, nb_nodes_per_element); Array::matrix_iterator bt_s_it = bt_s->begin(bt_s_size, 1); Matrix S_vect(stress_size, 1); Matrix B_tensor(stress_size, bt_s_size); Matrix B2_tensor(stress_size, bt_s_size); for (; grad_u_it != grad_u_end; ++grad_u_it, ++stress_it, ++shapes_derivatives_filtered_it, ++bt_s_it) { Matrix & grad_u = *grad_u_it; Matrix & r_it = *bt_s_it; Matrix & S_it = *stress_it; - SetCauchyStressArray (S_it, S_vect); + setCauchyStressArray (S_it, S_vect); VoigtHelper::transferBMatrixToSymVoigtBMatrix(*shapes_derivatives_filtered_it, B_tensor, nb_nodes_per_element); VoigtHelper::transferBMatrixToBL2(*shapes_derivatives_filtered_it, grad_u, B2_tensor, nb_nodes_per_element); B_tensor += B2_tensor; r_it.mul < true, false > (B_tensor, S_vect); } delete shapesd_filtered; /// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$ Array * r_e = new Array (nb_element, - bt_s_size, "r_e"); + bt_s_size, "r_e"); fem->integrate(*bt_s, *r_e, - bt_s_size, - *it, ghost_type, - elem_filter); + bt_s_size, + *it, ghost_type, + elem_filter); delete bt_s; fem->assembleArray(*r_e, residual, - model->getDOFSynchronizer().getLocalDOFEquationNumbers(), - residual.getNbComponent(), - *it, ghost_type, elem_filter, -1); + model->getDOFSynchronizer().getLocalDOFEquationNumbers(), + residual.getNbComponent(), + *it, ghost_type, elem_filter, -1); delete r_e; } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void Material::computeAllStressesFromTangentModuli(GhostType ghost_type) { AKANTU_DEBUG_IN(); UInt spatial_dimension = model->getSpatialDimension(); Mesh::type_iterator it = element_filter.firstType(spatial_dimension, ghost_type); Mesh::type_iterator last_type = element_filter.lastType(spatial_dimension, ghost_type); for(; it != last_type; ++it) { switch(spatial_dimension) { case 1: { computeAllStressesFromTangentModuli<1>(*it, ghost_type); break; } case 2: { computeAllStressesFromTangentModuli<2>(*it, ghost_type); break; } case 3: { computeAllStressesFromTangentModuli<3>(*it, ghost_type); break; } } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ template void Material::computeAllStressesFromTangentModuli(const ElementType & type, - GhostType ghost_type) { + GhostType ghost_type) { AKANTU_DEBUG_IN(); const Array & shapes_derivatives = fem->getShapesDerivatives(type, ghost_type); Array & elem_filter = element_filter(type, ghost_type); Array & gradu_vect = gradu(type, ghost_type); UInt nb_element = elem_filter.getSize(); if (nb_element) { UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type); UInt nb_quadrature_points = fem->getNbQuadraturePoints(type, ghost_type); gradu_vect.resize(nb_quadrature_points * nb_element); Array & disp = model->getDisplacement(); fem->gradientOnQuadraturePoints(disp, gradu_vect, - dim, type, ghost_type, elem_filter); + dim, type, ghost_type, elem_filter); UInt tangent_moduli_size = getTangentStiffnessVoigtSize(dim); Array * tangent_moduli_tensors = new Array(nb_element*nb_quadrature_points, tangent_moduli_size * tangent_moduli_size, - "tangent_moduli_tensors"); + "tangent_moduli_tensors"); tangent_moduli_tensors->clear(); computeTangentModuli(type, *tangent_moduli_tensors, ghost_type); Array * shapesd_filtered = new Array(0, dim* nb_nodes_per_element, "filtered shapesd"); FEEngine::filterElementalData(fem->getMesh(), shapes_derivatives, *shapesd_filtered, - type, ghost_type, elem_filter); + type, ghost_type, elem_filter); Array filtered_u(nb_element, nb_nodes_per_element * spatial_dimension); FEEngine::extractNodalToElementField(fem->getMesh(), disp, filtered_u, - type, ghost_type, elem_filter); + type, ghost_type, elem_filter); /// compute @f$\mathbf{D} \mathbf{B} \mathbf{u}@f$ Array::matrix_iterator shapes_derivatives_filtered_it = shapesd_filtered->begin(dim, nb_nodes_per_element); Array::matrix_iterator D_it = tangent_moduli_tensors->begin(tangent_moduli_size, - tangent_moduli_size); + tangent_moduli_size); Array::matrix_iterator sigma_it = stress(type, ghost_type).begin(spatial_dimension, - spatial_dimension); + spatial_dimension); Array::vector_iterator u_it = filtered_u.begin(spatial_dimension * nb_nodes_per_element); Matrix B(tangent_moduli_size, spatial_dimension * nb_nodes_per_element); Vector Bu(tangent_moduli_size); Vector DBu(tangent_moduli_size); for (UInt e = 0; e < nb_element; ++e, ++u_it) { for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it, ++shapes_derivatives_filtered_it, ++sigma_it) { - Vector & u = *u_it; - Matrix & sigma = *sigma_it; - Matrix & D = *D_it; - - VoigtHelper::transferBMatrixToSymVoigtBMatrix(*shapes_derivatives_filtered_it, B, nb_nodes_per_element); - - Bu.mul(B, u); - DBu.mul(D, Bu); - - // Voigt notation to full symmetric tensor - for (UInt i = 0; i < dim; ++i) sigma(i, i) = DBu(i); - if(dim == 2) { - sigma(0,1) = sigma(1,0) = DBu(2); - } else if(dim == 3) { - sigma(1,2) = sigma(2,1) = DBu(3); - sigma(0,2) = sigma(2,0) = DBu(4); - sigma(0,1) = sigma(1,0) = DBu(5); - } + Vector & u = *u_it; + Matrix & sigma = *sigma_it; + Matrix & D = *D_it; + + VoigtHelper::transferBMatrixToSymVoigtBMatrix(*shapes_derivatives_filtered_it, B, nb_nodes_per_element); + + Bu.mul(B, u); + DBu.mul(D, Bu); + + // Voigt notation to full symmetric tensor + for (UInt i = 0; i < dim; ++i) sigma(i, i) = DBu(i); + if(dim == 2) { + sigma(0,1) = sigma(1,0) = DBu(2); + } else if(dim == 3) { + sigma(1,2) = sigma(2,1) = DBu(3); + sigma(0,2) = sigma(2,0) = DBu(4); + sigma(0,1) = sigma(1,0) = DBu(5); + } } } } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void Material::computePotentialEnergyByElements() { AKANTU_DEBUG_IN(); Mesh::type_iterator it = element_filter.firstType(spatial_dimension); Mesh::type_iterator last_type = element_filter.lastType(spatial_dimension); for(; it != last_type; ++it) { computePotentialEnergy(*it); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void Material::computePotentialEnergy(ElementType el_type, GhostType ghost_type) { AKANTU_DEBUG_IN(); if(!potential_energy.exists(el_type, ghost_type)) { UInt nb_element = element_filter(el_type, ghost_type).getSize(); UInt nb_quadrature_points = fem->getNbQuadraturePoints(el_type, _not_ghost); potential_energy.alloc(nb_element * nb_quadrature_points, 1, - el_type, ghost_type); + el_type, ghost_type); } AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ Real Material::getPotentialEnergy() { AKANTU_DEBUG_IN(); Real epot = 0.; computePotentialEnergyByElements(); /// integrate the potential energy for each type of elements Mesh::type_iterator it = element_filter.firstType(spatial_dimension); Mesh::type_iterator last_type = element_filter.lastType(spatial_dimension); for(; it != last_type; ++it) { epot += fem->integrate(potential_energy(*it, _not_ghost), *it, - _not_ghost, element_filter(*it, _not_ghost)); + _not_ghost, element_filter(*it, _not_ghost)); } AKANTU_DEBUG_OUT(); return epot; } /* -------------------------------------------------------------------------- */ Real Material::getPotentialEnergy(ElementType & type, UInt index) { AKANTU_DEBUG_IN(); Real epot = 0.; Vector epot_on_quad_points(fem->getNbQuadraturePoints(type)); computePotentialEnergyByElement(type, index, epot_on_quad_points); epot = fem->integrate(epot_on_quad_points, type, element_filter(type)(index)); AKANTU_DEBUG_OUT(); return epot; } /* -------------------------------------------------------------------------- */ Real Material::getEnergy(std::string type) { AKANTU_DEBUG_IN(); if(type == "potential") return getPotentialEnergy(); AKANTU_DEBUG_OUT(); return 0.; } /* -------------------------------------------------------------------------- */ Real Material::getEnergy(std::string energy_id, ElementType type, UInt index) { AKANTU_DEBUG_IN(); if(energy_id == "potential") return getPotentialEnergy(type, index); AKANTU_DEBUG_OUT(); return 0.; } /* -------------------------------------------------------------------------- */ void Material::initElementalFieldInterpolation(const ElementTypeMapArray & interpolation_points_coordinates) { AKANTU_DEBUG_IN(); this->fem->initElementalFieldInterpolationFromControlPoints(interpolation_points_coordinates, - this->interpolation_points_matrices, - this->interpolation_inverse_coordinates, - &(this->element_filter)); + this->interpolation_points_matrices, + this->interpolation_inverse_coordinates, + &(this->element_filter)); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void Material::interpolateStress(ElementTypeMapArray & result, - const GhostType ghost_type) { + const GhostType ghost_type) { this->fem->interpolateElementalFieldFromControlPoints(this->stress, - this->interpolation_points_matrices, - this->interpolation_inverse_coordinates, - result, - ghost_type, - &(this->element_filter)); + this->interpolation_points_matrices, + this->interpolation_inverse_coordinates, + result, + ghost_type, + &(this->element_filter)); } /* -------------------------------------------------------------------------- */ void Material::interpolateStressOnFacets(ElementTypeMapArray & result, - const GhostType ghost_type) { + const GhostType ghost_type) { ElementTypeMapArray by_elem_result; interpolateStress(by_elem_result, ghost_type); UInt stress_size = this->stress.getNbComponent(); const Mesh & mesh = this->model->getMesh(); const Mesh & mesh_facets = mesh.getMeshFacets(); Mesh::type_iterator it = this->element_filter.firstType(spatial_dimension, ghost_type); Mesh::type_iterator last = this->element_filter.lastType(spatial_dimension, ghost_type); for (; it != last; ++it) { ElementType type = *it; Array & elem_fil = element_filter(type, ghost_type); Array & by_elem_res = by_elem_result(type, ghost_type); UInt nb_element = elem_fil.getSize(); UInt nb_interpolation_points_per_elem = by_elem_res.getSize() / nb_element; const Array & facet_to_element = mesh_facets.getSubelementToElement(type, ghost_type); ElementType type_facet = Mesh::getFacetType(type); UInt nb_facet_per_elem = facet_to_element.getNbComponent(); UInt nb_quad_per_facet = nb_interpolation_points_per_elem / nb_facet_per_elem; Element element_for_comparison(type, 0, ghost_type); const Array< std::vector > * element_to_facet = NULL; GhostType current_ghost_type = _casper; Array * result_vec = NULL; Array::const_matrix_iterator result_it = by_elem_res.begin_reinterpret(stress_size, - nb_interpolation_points_per_elem, - nb_element); + nb_interpolation_points_per_elem, + nb_element); for (UInt el = 0; el < nb_element; ++el){ UInt global_el = elem_fil(el); element_for_comparison.element = global_el; for (UInt f = 0; f < nb_facet_per_elem; ++f) { - Element facet_elem = facet_to_element(global_el, f); - UInt global_facet = facet_elem.element; - if (facet_elem.ghost_type != current_ghost_type) { - current_ghost_type = facet_elem.ghost_type; - element_to_facet = &mesh_facets.getElementToSubelement(type_facet, - current_ghost_type); - result_vec = &result(type_facet, current_ghost_type); - } - - bool is_second_element = (*element_to_facet)(global_facet)[0] != element_for_comparison; - - for (UInt q = 0; q < nb_quad_per_facet; ++q) { - Vector result_local(result_vec->storage() - + (global_facet * nb_quad_per_facet + q) * result_vec->getNbComponent() - + is_second_element * stress_size, - stress_size); - - Matrix result_tmp(result_it[elem_fil(el)]); - result_local = result_tmp(f * nb_quad_per_facet + q); - } + Element facet_elem = facet_to_element(global_el, f); + UInt global_facet = facet_elem.element; + if (facet_elem.ghost_type != current_ghost_type) { + current_ghost_type = facet_elem.ghost_type; + element_to_facet = &mesh_facets.getElementToSubelement(type_facet, + current_ghost_type); + result_vec = &result(type_facet, current_ghost_type); + } + + bool is_second_element = (*element_to_facet)(global_facet)[0] != element_for_comparison; + + for (UInt q = 0; q < nb_quad_per_facet; ++q) { + Vector result_local(result_vec->storage() + + (global_facet * nb_quad_per_facet + q) * result_vec->getNbComponent() + + is_second_element * stress_size, + stress_size); + + Matrix result_tmp(result_it[elem_fil(el)]); + result_local = result_tmp(f * nb_quad_per_facet + q); + } } } } } /* -------------------------------------------------------------------------- */ template const Array & Material::getArray(const ID & vect_id, const ElementType & type, const GhostType & ghost_type) const { AKANTU_DEBUG_TO_IMPLEMENT(); return NULL; } /* -------------------------------------------------------------------------- */ template Array & Material::getArray(const ID & vect_id, const ElementType & type, const GhostType & ghost_type) { AKANTU_DEBUG_TO_IMPLEMENT(); return NULL; } /* -------------------------------------------------------------------------- */ template<> const Array & Material::getArray(const ID & vect_id, const ElementType & type, const GhostType & ghost_type) const { std::stringstream sstr; std::string ghost_id = ""; if (ghost_type == _ghost) ghost_id = ":ghost"; sstr << getID() << ":" << vect_id << ":" << type << ghost_id; ID fvect_id = sstr.str(); try { return Memory::getArray(fvect_id); } catch(debug::Exception & e) { AKANTU_SILENT_EXCEPTION("The material " << name << "(" < Array & Material::getArray(const ID & vect_id, const ElementType & type, const GhostType & ghost_type) { std::stringstream sstr; std::string ghost_id = ""; if (ghost_type == _ghost) ghost_id = ":ghost"; sstr << getID() << ":" << vect_id << ":" << type << ghost_id; ID fvect_id = sstr.str(); try { return Memory::getArray(fvect_id); } catch(debug::Exception & e) { AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID() << ") does not contain a vector " << vect_id << "(" << fvect_id << ") [" << e << "]"); } } /* -------------------------------------------------------------------------- */ template const InternalField & Material::getInternal(const ID & int_id) const { AKANTU_DEBUG_TO_IMPLEMENT(); return NULL; } /* -------------------------------------------------------------------------- */ template InternalField & Material::getInternal(const ID & int_id) { AKANTU_DEBUG_TO_IMPLEMENT(); return NULL; } /* -------------------------------------------------------------------------- */ template<> const InternalField & Material::getInternal(const ID & int_id) const { std::map *>::const_iterator it = internal_vectors_real.find(getID() + ":" + int_id); if(it == internal_vectors_real.end()) { AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID() - << ") does not contain an internal " - << int_id << " (" << (getID() + ":" + int_id) << ")"); + << ") does not contain an internal " + << int_id << " (" << (getID() + ":" + int_id) << ")"); } return *it->second; } /* -------------------------------------------------------------------------- */ template<> InternalField & Material::getInternal(const ID & int_id) { std::map *>::iterator it = internal_vectors_real.find(getID() + ":" + int_id); if(it == internal_vectors_real.end()) { AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID() - << ") does not contain an internal " - << int_id << " (" << (getID() + ":" + int_id) << ")"); + << ") does not contain an internal " + << int_id << " (" << (getID() + ":" + int_id) << ")"); } return *it->second; } /* -------------------------------------------------------------------------- */ template<> const InternalField & Material::getInternal(const ID & int_id) const { std::map *>::const_iterator it = internal_vectors_uint.find(getID() + ":" + int_id); if(it == internal_vectors_uint.end()) { AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID() - << ") does not contain an internal " - << int_id << " (" << (getID() + ":" + int_id) << ")"); + << ") does not contain an internal " + << int_id << " (" << (getID() + ":" + int_id) << ")"); } return *it->second; } /* -------------------------------------------------------------------------- */ template<> InternalField & Material::getInternal(const ID & int_id) { std::map *>::iterator it = internal_vectors_uint.find(getID() + ":" + int_id); if(it == internal_vectors_uint.end()) { AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID() - << ") does not contain an internal " - << int_id << " (" << (getID() + ":" + int_id) << ")"); + << ") does not contain an internal " + << int_id << " (" << (getID() + ":" + int_id) << ")"); } return *it->second; } /* -------------------------------------------------------------------------- */ void Material::addElements(const Array & elements_to_add) { AKANTU_DEBUG_IN(); UInt mat_id = model->getInternalIndexFromID(getID()); Array::const_iterator el_begin = elements_to_add.begin(); Array::const_iterator el_end = elements_to_add.end(); for(;el_begin != el_end; ++el_begin) { const Element & element = *el_begin; Array & mat_indexes = model->getMaterialByElement (element.type, element.ghost_type); Array & mat_loc_num = model->getMaterialLocalNumbering(element.type, element.ghost_type); UInt index = this->addElement(element.type, element.element, element.ghost_type); mat_indexes(element.element) = mat_id; mat_loc_num(element.element) = index; } this->resizeInternals(); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void Material::removeElements(const Array & elements_to_remove) { AKANTU_DEBUG_IN(); Array::const_iterator el_begin = elements_to_remove.begin(); Array::const_iterator el_end = elements_to_remove.end(); if(el_begin==el_end) return; ElementTypeMapArray material_local_new_numbering("remove mat filter elem", getID()); Element element; for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) { GhostType ghost_type = *gt; element.ghost_type = ghost_type; ElementTypeMapArray::type_iterator it = element_filter.firstType(_all_dimensions, ghost_type, _ek_not_defined); ElementTypeMapArray::type_iterator end = element_filter.lastType(_all_dimensions, ghost_type, _ek_not_defined); for(; it != end; ++it) { ElementType type = *it; element.type = type; Array & elem_filter = this->element_filter(type, ghost_type); Array & mat_loc_num = this->model->getMaterialLocalNumbering(type, ghost_type); if(!material_local_new_numbering.exists(type, ghost_type)) - material_local_new_numbering.alloc(elem_filter.getSize(), 1, type, ghost_type); + material_local_new_numbering.alloc(elem_filter.getSize(), 1, type, ghost_type); Array & mat_renumbering = material_local_new_numbering(type, ghost_type); UInt nb_element = elem_filter.getSize(); element.kind=(*el_begin).kind; Array elem_filter_tmp; UInt new_id = 0; for (UInt el = 0; el < nb_element; ++el) { - element.element = elem_filter(el); + element.element = elem_filter(el); - if(std::find(el_begin, el_end, element) == el_end) { - elem_filter_tmp.push_back(element.element); + if(std::find(el_begin, el_end, element) == el_end) { + elem_filter_tmp.push_back(element.element); - mat_renumbering(el) = new_id; - mat_loc_num(element.element) = new_id; - ++new_id; - } else { - mat_renumbering(el) = UInt(-1); - } + mat_renumbering(el) = new_id; + mat_loc_num(element.element) = new_id; + ++new_id; + } else { + mat_renumbering(el) = UInt(-1); + } } elem_filter.resize(elem_filter_tmp.getSize()); elem_filter.copy(elem_filter_tmp); } } for (std::map *>::iterator it = internal_vectors_real.begin(); it != internal_vectors_real.end(); ++it) it->second->removeQuadraturePoints(material_local_new_numbering); for (std::map *>::iterator it = internal_vectors_uint.begin(); it != internal_vectors_uint.end(); ++it) it->second->removeQuadraturePoints(material_local_new_numbering); for (std::map *>::iterator it = internal_vectors_bool.begin(); it != internal_vectors_bool.end(); ++it) it->second->removeQuadraturePoints(material_local_new_numbering); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void Material::resizeInternals() { AKANTU_DEBUG_IN(); for (std::map *>::iterator it = internal_vectors_real.begin(); it != internal_vectors_real.end(); ++it) it->second->resize(); for (std::map *>::iterator it = internal_vectors_uint.begin(); it != internal_vectors_uint.end(); ++it) it->second->resize(); for (std::map *>::iterator it = internal_vectors_bool.begin(); it != internal_vectors_bool.end(); ++it) it->second->resize(); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ void Material::onElementsAdded(__attribute__((unused)) const Array & element_list, - __attribute__((unused)) const NewElementsEvent & event) { + __attribute__((unused)) const NewElementsEvent & event) { this->resizeInternals(); } /* -------------------------------------------------------------------------- */ void Material::onElementsRemoved(const Array & element_list, - const ElementTypeMapArray & new_numbering, - __attribute__((unused)) const RemovedElementsEvent & event) { + const ElementTypeMapArray & new_numbering, + __attribute__((unused)) const RemovedElementsEvent & event) { UInt my_num = model->getInternalIndexFromID(getID()); ElementTypeMapArray material_local_new_numbering("remove mat filter elem", getID()); Array::const_iterator el_begin = element_list.begin(); Array::const_iterator el_end = element_list.end(); for (ghost_type_t::iterator g = ghost_type_t::begin(); g != ghost_type_t::end(); ++g) { GhostType gt = *g; ElementTypeMapArray::type_iterator it = new_numbering.firstType(_all_dimensions, gt, _ek_not_defined); ElementTypeMapArray::type_iterator end = new_numbering.lastType (_all_dimensions, gt, _ek_not_defined); for (; it != end; ++it) { ElementType type = *it; if(element_filter.exists(type, gt) && element_filter(type, gt).getSize()){ - Array & elem_filter = element_filter(type, gt); - - Array & mat_indexes = this->model->getMaterialByElement (*it, gt); - Array & mat_loc_num = this->model->getMaterialLocalNumbering(*it, gt); - UInt nb_element = this->model->getMesh().getNbElement(type, gt); - - // all materials will resize of the same size... - mat_indexes.resize(nb_element); - mat_loc_num.resize(nb_element); - - if(!material_local_new_numbering.exists(type, gt)) - material_local_new_numbering.alloc(elem_filter.getSize(), 1, type, gt); - - Array & mat_renumbering = material_local_new_numbering(type, gt); - const Array & renumbering = new_numbering(type, gt); - Array elem_filter_tmp; - UInt ni = 0; - Element el; - el.type = type; - el.ghost_type = gt; - el.kind = Mesh::getKind(type); - for (UInt i = 0; i < elem_filter.getSize(); ++i) { - el.element = elem_filter(i); - if(std::find(el_begin, el_end, el) == el_end) { - UInt new_el = renumbering(el.element); - AKANTU_DEBUG_ASSERT(new_el != UInt(-1), "A not removed element as been badly renumbered"); - elem_filter_tmp.push_back(new_el); - mat_renumbering(i) = ni; - - mat_indexes(new_el) = my_num; - mat_loc_num(new_el) = ni; - ++ni; - } else { - mat_renumbering(i) = UInt(-1); - } - } - - elem_filter.resize(elem_filter_tmp.getSize()); - elem_filter.copy(elem_filter_tmp); + Array & elem_filter = element_filter(type, gt); + + Array & mat_indexes = this->model->getMaterialByElement (*it, gt); + Array & mat_loc_num = this->model->getMaterialLocalNumbering(*it, gt); + UInt nb_element = this->model->getMesh().getNbElement(type, gt); + + // all materials will resize of the same size... + mat_indexes.resize(nb_element); + mat_loc_num.resize(nb_element); + + if(!material_local_new_numbering.exists(type, gt)) + material_local_new_numbering.alloc(elem_filter.getSize(), 1, type, gt); + + Array & mat_renumbering = material_local_new_numbering(type, gt); + const Array & renumbering = new_numbering(type, gt); + Array elem_filter_tmp; + UInt ni = 0; + Element el; + el.type = type; + el.ghost_type = gt; + el.kind = Mesh::getKind(type); + for (UInt i = 0; i < elem_filter.getSize(); ++i) { + el.element = elem_filter(i); + if(std::find(el_begin, el_end, el) == el_end) { + UInt new_el = renumbering(el.element); + AKANTU_DEBUG_ASSERT(new_el != UInt(-1), "A not removed element as been badly renumbered"); + elem_filter_tmp.push_back(new_el); + mat_renumbering(i) = ni; + + mat_indexes(new_el) = my_num; + mat_loc_num(new_el) = ni; + ++ni; + } else { + mat_renumbering(i) = UInt(-1); + } + } + + elem_filter.resize(elem_filter_tmp.getSize()); + elem_filter.copy(elem_filter_tmp); } } } for (std::map *>::iterator it = internal_vectors_real.begin(); it != internal_vectors_real.end(); ++it) it->second->removeQuadraturePoints(material_local_new_numbering); for (std::map *>::iterator it = internal_vectors_uint.begin(); it != internal_vectors_uint.end(); ++it) it->second->removeQuadraturePoints(material_local_new_numbering); for (std::map *>::iterator it = internal_vectors_bool.begin(); it != internal_vectors_bool.end(); ++it) it->second->removeQuadraturePoints(material_local_new_numbering); } /* -------------------------------------------------------------------------- */ void Material::onBeginningSolveStep(const AnalysisMethod & method) { this->savePreviousState(); } /* -------------------------------------------------------------------------- */ void Material::onEndSolveStep(const AnalysisMethod & method) { ElementTypeMapArray::type_iterator it = this->element_filter.firstType(_all_dimensions, _not_ghost, _ek_not_defined); ElementTypeMapArray::type_iterator end = element_filter.lastType(_all_dimensions, _not_ghost, _ek_not_defined); for(; it != end; ++it) { this->updateEnergies(*it, _not_ghost); } } /* -------------------------------------------------------------------------- */ void Material::onDamageIteration() { this->savePreviousState(); } /* -------------------------------------------------------------------------- */ void Material::onDamageUpdate() { ElementTypeMapArray::type_iterator it = this->element_filter.firstType(_all_dimensions, _not_ghost, _ek_not_defined); ElementTypeMapArray::type_iterator end = element_filter.lastType(_all_dimensions, _not_ghost, _ek_not_defined); for(; it != end; ++it) { if(!this->potential_energy.exists(*it, _not_ghost)) { UInt nb_element = this->element_filter(*it, _not_ghost).getSize(); UInt nb_quadrature_points = this->fem->getNbQuadraturePoints(*it, _not_ghost); this->potential_energy.alloc(nb_element * nb_quadrature_points, 1, - *it, _not_ghost); + *it, _not_ghost); } this->updateEnergiesAfterDamage(*it, _not_ghost); } } /* -------------------------------------------------------------------------- */ void Material::onDump(){ if(this->isFiniteDeformation()) this->computeAllCauchyStresses(_not_ghost); } /* -------------------------------------------------------------------------- */ void Material::printself(std::ostream & stream, int indent) const { std::string space; for(Int i = 0; i < indent; i++, space += AKANTU_INDENT); std::string type = getID().substr(getID().find_last_of(":") + 1); stream << space << "Material " << type << " [" << std::endl; Parsable::printself(stream, indent); stream << space << "]" << std::endl; } /* -------------------------------------------------------------------------- */ inline ElementTypeMap Material::getInternalDataPerElem(const ID & id, const ElementKind & element_kind, const ID & fe_engine_id) const { std::map *>::const_iterator internal_array = internal_vectors_real.find(this->getID()+":"+id); if (internal_array == internal_vectors_real.end() || internal_array->second->getElementKind() != element_kind) AKANTU_EXCEPTION("Cannot find internal field " << id << " in material " << this->name); InternalField & internal = *internal_array->second; InternalField::type_iterator it = internal.firstType(internal.getSpatialDimension(), - _not_ghost, element_kind); + _not_ghost, element_kind); InternalField::type_iterator last_type = internal.lastType(internal.getSpatialDimension(), - _not_ghost, element_kind); + _not_ghost, element_kind); ElementTypeMap res; for(; it != last_type; ++it) { UInt nb_quadrature_points = 0; nb_quadrature_points = model->getFEEngine(fe_engine_id).getNbQuadraturePoints(*it); res(*it) = internal.getNbComponent() * nb_quadrature_points; } return res; } /* -------------------------------------------------------------------------- */ void Material::flattenInternal(const std::string & field_id, - ElementTypeMapArray & internal_flat, - const GhostType ghost_type, - ElementKind element_kind) const { + ElementTypeMapArray & internal_flat, + const GhostType ghost_type, + ElementKind element_kind) const { this->flattenInternalIntern(field_id, internal_flat, - this->spatial_dimension, - ghost_type, element_kind); + this->spatial_dimension, + ghost_type, element_kind); } /* -------------------------------------------------------------------------- */ void Material::flattenInternalIntern(const std::string & field_id, - ElementTypeMapArray & internal_flat, - UInt spatial_dimension, - const GhostType ghost_type, - ElementKind element_kind, - const ElementTypeMapArray * element_filter, - const Mesh * mesh) const { + ElementTypeMapArray & internal_flat, + UInt spatial_dimension, + const GhostType ghost_type, + ElementKind element_kind, + const ElementTypeMapArray * element_filter, + const Mesh * mesh) const { typedef ElementTypeMapArray::type_iterator iterator; if(element_filter == NULL) element_filter = &(this->element_filter); if(mesh == NULL) mesh = &(this->model->mesh); iterator tit = element_filter->firstType(spatial_dimension, - ghost_type, - element_kind); + ghost_type, + element_kind); iterator end = element_filter->lastType(spatial_dimension, - ghost_type, - element_kind); + ghost_type, + element_kind); for (; tit != end; ++tit) { ElementType type = *tit; try { __attribute__((unused)) const Array & src_vect - = this->getArray(field_id, type, ghost_type); + = this->getArray(field_id, type, ghost_type); } catch(debug::Exception & e) { continue; } const Array & src_vect = this->getArray(field_id, type, ghost_type); const Array & filter = (*element_filter)(type, ghost_type); // total number of elements for a given type UInt nb_element = mesh->getNbElement(type,ghost_type); // number of filtered elements UInt nb_element_src = filter.getSize(); // number of quadrature points per elem UInt nb_quad_per_elem = 0; // number of data per quadrature point UInt nb_data_per_quad = src_vect.getNbComponent(); if (!internal_flat.exists(type,ghost_type)) { internal_flat.alloc(nb_element * nb_quad_per_elem, - nb_data_per_quad, - type, - ghost_type); + nb_data_per_quad, + type, + ghost_type); } if (nb_element_src == 0) continue; nb_quad_per_elem = (src_vect.getSize() / nb_element_src); // number of data per element UInt nb_data = nb_quad_per_elem * src_vect.getNbComponent(); Array & dst_vect = internal_flat(type,ghost_type); dst_vect.resize(nb_element*nb_quad_per_elem); Array::const_scalar_iterator it = filter.begin(); Array::const_scalar_iterator end = filter.end(); Array::const_vector_iterator it_src = src_vect.begin_reinterpret(nb_data, nb_element_src); Array::vector_iterator it_dst = dst_vect.begin_reinterpret(nb_data, nb_element); for (; it != end ; ++it,++it_src) { it_dst[*it] = *it_src; } } }; /* -------------------------------------------------------------------------- */ /// extrapolate internal values void Material::extrapolateInternal(const ID & id, const Element & element, const Matrix & point, Matrix & extrapolated) { if (this->isInternal(id, element.kind)) { UInt nb_element = this->element_filter(element.type, element.ghost_type).getSize(); const ID name = this->getID() + ":" + id; UInt nb_quads = this->internal_vectors_real[name]->getFEEngine().getNbQuadraturePoints(element.type, element.ghost_type); const Array & internal = this->getArray(id, element.type, element.ghost_type); UInt nb_component = internal.getNbComponent(); Array::const_matrix_iterator internal_it = internal.begin_reinterpret(nb_component, nb_quads, nb_element); Element local_element = this->convertToLocalElement(element); /// instead of really extrapolating, here the value of the first GP /// is copied into the result vector. This works only for linear /// elements /// @todo extrapolate!!!! const Matrix & values = internal_it[local_element.element]; UInt index = 0; Vector tmp(nb_component); for (UInt j = 0; j < values.cols(); ++j) { tmp = values(j); - if (tmp.norm() > 0) { - index = j; - continue; + if (tmp.norm() > 0) { + index = j; + continue; } } - + for (UInt i = 0; i < extrapolated.size(); ++i) { extrapolated(i) = values(index); } } else { Matrix default_values(extrapolated.rows(), extrapolated.cols(), 0.); extrapolated = default_values; } } __END_AKANTU__ diff --git a/src/model/solid_mechanics/material.hh b/src/model/solid_mechanics/material.hh index 909ec2c84..0d9150118 100644 --- a/src/model/solid_mechanics/material.hh +++ b/src/model/solid_mechanics/material.hh @@ -1,613 +1,632 @@ /** * @file material.hh * * @author Marco Vocialta * @author Nicolas Richart * @author Daniel Pino Muñoz * * @date creation: Tue Jul 27 2010 * @date last modification: Tue Sep 16 2014 * * @brief Mother class for all materials * * @section LICENSE * * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "aka_common.hh" #include "aka_memory.hh" #include "aka_voigthelper.hh" #include "parser.hh" #include "parsable.hh" #include "data_accessor.hh" #include "internal_field.hh" #include "random_internal_field.hh" #include "solid_mechanics_model_event_handler.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MATERIAL_HH__ #define __AKANTU_MATERIAL_HH__ /* -------------------------------------------------------------------------- */ namespace akantu { class Model; class SolidMechanicsModel; } __BEGIN_AKANTU__ /** * Interface of all materials * Prerequisites for a new material * - inherit from this class * - implement the following methods: * \code * virtual Real getStableTimeStep(Real h, const Element & element = ElementNull); * * virtual void computeStress(ElementType el_type, * GhostType ghost_type = _not_ghost); * * virtual void computeTangentStiffness(const ElementType & el_type, * Array & tangent_matrix, * GhostType ghost_type = _not_ghost); * \endcode * */ class Material : public Memory, public DataAccessor, public Parsable, public MeshEventHandler, protected SolidMechanicsModelEventHandler { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: #if __cplusplus > 199711L Material(const Material & mat) = delete; Material & operator=(const Material & mat) = delete; #endif /// Initialize material with defaults Material(SolidMechanicsModel & model, const ID & id = ""); /// Initialize material with custom mesh & fe_engine Material(SolidMechanicsModel & model, UInt dim, const Mesh & mesh, FEEngine & fe_engine, const ID & id = ""); /// Destructor virtual ~Material(); protected: void initialize(); /* ------------------------------------------------------------------------ */ /* Function that materials can/should reimplement */ /* ------------------------------------------------------------------------ */ protected: /// constitutive law virtual void computeStress(__attribute__((unused)) ElementType el_type, __attribute__((unused)) GhostType ghost_type = _not_ghost) { AKANTU_DEBUG_TO_IMPLEMENT(); } /// compute the tangent stiffness matrix virtual void computeTangentModuli(__attribute__((unused)) const ElementType & el_type, __attribute__((unused)) Array & tangent_matrix, __attribute__((unused)) GhostType ghost_type = _not_ghost) { AKANTU_DEBUG_TO_IMPLEMENT(); } /// compute the potential energy virtual void computePotentialEnergy(ElementType el_type, GhostType ghost_type = _not_ghost); /// compute the potential energy for an element virtual void computePotentialEnergyByElement(__attribute__((unused)) ElementType type, - __attribute__((unused)) UInt index, + __attribute__((unused)) UInt index, __attribute__((unused)) Vector & epot_on_quad_points) { AKANTU_DEBUG_TO_IMPLEMENT(); } virtual void updateEnergies(__attribute__((unused)) ElementType el_type, __attribute__((unused)) GhostType ghost_type = _not_ghost) { } virtual void updateEnergiesAfterDamage(__attribute__((unused)) ElementType el_type, - __attribute__((unused)) GhostType ghost_type = _not_ghost) {} + __attribute__((unused)) GhostType ghost_type = _not_ghost) {} /// set the material to steady state (to be implemented for materials that need it) virtual void setToSteadyState(__attribute__((unused)) ElementType el_type, __attribute__((unused)) GhostType ghost_type = _not_ghost) { } /// function called to update the internal parameters when the modifiable /// parameters are modified virtual void updateInternalParameters() {} public: /// extrapolate internal values virtual void extrapolateInternal(const ID & id, const Element & element, const Matrix & points, Matrix & extrapolated); /// compute the p-wave speed in the material virtual Real getPushWaveSpeed(const Element & element) const { AKANTU_DEBUG_TO_IMPLEMENT(); } /// compute the s-wave speed in the material virtual Real getShearWaveSpeed(const Element & element) const { AKANTU_DEBUG_TO_IMPLEMENT(); } /// get a material celerity to compute the stable time step (default: is the push wave speed) virtual Real getCelerity(const Element & element) const { return getPushWaveSpeed(element); } /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: template void registerInternal(__attribute__((unused)) InternalField & vect) { AKANTU_DEBUG_TO_IMPLEMENT(); } template void unregisterInternal(__attribute__((unused)) InternalField & vect) { AKANTU_DEBUG_TO_IMPLEMENT(); } /// initialize the material computed parameter virtual void initMaterial(); /// compute the residual for this material virtual void updateResidual(GhostType ghost_type = _not_ghost); /// assemble the residual for this material virtual void assembleResidual(GhostType ghost_type); /// Operations before and after solveStep in implicit virtual void beforeSolveStep() {} virtual void afterSolveStep() {} /// save the stress in the previous_stress if needed virtual void savePreviousState(); /// compute the stresses for this material virtual void computeAllStresses(GhostType ghost_type = _not_ghost); virtual void computeAllNonLocalStresses(__attribute__((unused)) GhostType ghost_type = _not_ghost) {}; virtual void computeAllStressesFromTangentModuli(GhostType ghost_type = _not_ghost); virtual void computeAllCauchyStresses(GhostType ghost_type = _not_ghost); /// set material to steady state void setToSteadyState(GhostType ghost_type = _not_ghost); /// compute the stiffness matrix virtual void assembleStiffnessMatrix(GhostType ghost_type); /// add an element to the local mesh filter inline UInt addElement(const ElementType & type, UInt element, const GhostType & ghost_type); /// add many elements at once void addElements(const Array & elements_to_add); /// remove many element at once void removeElements(const Array & elements_to_remove); /// function to print the contain of the class virtual void printself(std::ostream & stream, int indent = 0) const; /** * interpolate stress on given positions for each element by means * of a geometrical interpolation on quadrature points */ void interpolateStress(ElementTypeMapArray & result, const GhostType ghost_type = _not_ghost); /** * interpolate stress on given positions for each element by means * of a geometrical interpolation on quadrature points and store the * results per facet */ void interpolateStressOnFacets(ElementTypeMapArray & result, - const GhostType ghost_type = _not_ghost); + const GhostType ghost_type = _not_ghost); /** * function to initialize the elemental field interpolation * function by inverting the quadrature points' coordinates */ void initElementalFieldInterpolation(const ElementTypeMapArray & interpolation_points_coordinates); /* ------------------------------------------------------------------------ */ /* Common part */ /* ------------------------------------------------------------------------ */ protected: + /* ------------------------------------------------------------------------ */ + inline UInt getTangentStiffnessVoigtSize(UInt spatial_dimension) const; + + + /// compute the potential energy by element + void computePotentialEnergyByElements(); + + /// resize the intenals arrays + virtual void resizeInternals(); + /* ------------------------------------------------------------------------ */ + /* Finite deformation functions */ + /* This functions area implementing what is described in the paper of Bathe */ + /* et al, in IJNME, Finite Element Formulations For Large Deformation */ + /* Dynamic Analysis, Vol 9, 353-386, 1975 */ + /* ------------------------------------------------------------------------ */ +protected: /// assemble the residual template void assembleResidual(GhostType ghost_type); - /// Computation of Cauchy stress tensor in the case of finite deformation + /// Computation of Cauchy stress tensor in the case of finite deformation from + /// the 2nd Piola-Kirchhoff for a given element type template void computeCauchyStress(__attribute__((unused)) ElementType el_type, __attribute__((unused)) GhostType ghost_type = _not_ghost); + /// Computation the Cauchy stress the 2nd Piola-Kirchhoff and the deformation + /// gradient template inline void computeCauchyStressOnQuad(const Matrix & F, const Matrix & S, - Matrix & cauchy, - const Real & C33 = 1.0 ) const; + Matrix & cauchy, + const Real & C33 = 1.0) const; template void computeAllStressesFromTangentModuli(const ElementType & type, - GhostType ghost_type); + GhostType ghost_type); template void assembleStiffnessMatrix(const ElementType & type, GhostType ghost_type); /// assembling in finite deformation template void assembleStiffnessMatrixNL(const ElementType & type, GhostType ghost_type); template void assembleStiffnessMatrixL2(const ElementType & type, GhostType ghost_type); - /// write the stress tensor in the Voigt notation. - template - inline void SetCauchyStressArray(const Matrix & S_t, Matrix & Stress_vect); - - inline UInt getTangentStiffnessVoigtSize(UInt spatial_dimension) const; - - /// Size of the Stress matrix for the case of finite deformation see: Bathe et al, IJNME, Vol 9, 353-386, 1975 + /// Size of the Stress matrix for the case of finite deformation see: Bathe et + /// al, IJNME, Vol 9, 353-386, 1975 inline UInt getCauchyStressMatrixSize(UInt spatial_dimension) const; /// Sets the stress matrix according to Bathe et al, IJNME, Vol 9, 353-386, 1975 template inline void setCauchyStressMatrix(const Matrix & S_t, - Matrix & Stress_matrix); - - /// compute the potential energy by element - void computePotentialEnergyByElements(); + Matrix & sigma); - /// resize the intenals arrays - virtual void resizeInternals(); + /// write the stress tensor in the Voigt notation. + template + inline void setCauchyStressArray(const Matrix & S_t, + Matrix & sigma_voight); -public: /* ------------------------------------------------------------------------ */ /* Conversion functions */ /* ------------------------------------------------------------------------ */ +public: template static inline void gradUToF (const Matrix & grad_u, Matrix & F); static inline void rightCauchy(const Matrix & F, Matrix & C); static inline void leftCauchy (const Matrix & F, Matrix & B); template static inline void gradUToEpsilon(const Matrix & grad_u, - Matrix & epsilon); + Matrix & epsilon); template static inline void gradUToGreenStrain(const Matrix & grad_u, - Matrix & epsilon); + Matrix & epsilon); static inline Real stressToVonMises(const Matrix & stress); protected: /// converts global element to local element inline Element convertToLocalElement(const Element & global_element) const; /// converts local element to global element inline Element convertToGlobalElement(const Element & local_element) const; /// converts global quadrature point to local quadrature point inline QuadraturePoint convertToLocalPoint(const QuadraturePoint & global_point) const; /// converts local quadrature point to global quadrature point inline QuadraturePoint convertToGlobalPoint(const QuadraturePoint & local_point) const; /* ------------------------------------------------------------------------ */ /* DataAccessor inherited members */ /* ------------------------------------------------------------------------ */ public: virtual inline UInt getNbDataForElements(const Array & elements, SynchronizationTag tag) const; virtual inline void packElementData(CommunicationBuffer & buffer, const Array & elements, SynchronizationTag tag) const; virtual inline void unpackElementData(CommunicationBuffer & buffer, const Array & elements, SynchronizationTag tag); template inline void packElementDataHelper(const ElementTypeMapArray & data_to_pack, CommunicationBuffer & buffer, const Array & elements, const ID & fem_id = ID()) const; template inline void unpackElementDataHelper(ElementTypeMapArray & data_to_unpack, CommunicationBuffer & buffer, const Array & elements, const ID & fem_id = ID()); /* ------------------------------------------------------------------------ */ /* MeshEventHandler inherited members */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ virtual void onElementsAdded(const Array & element_list, const NewElementsEvent & event); virtual void onElementsRemoved(const Array & element_list, const ElementTypeMapArray & new_numbering, const RemovedElementsEvent & event); /* ------------------------------------------------------------------------ */ /* SolidMechanicsModelEventHandler inherited members */ /* ------------------------------------------------------------------------ */ public: virtual void onBeginningSolveStep(const AnalysisMethod & method); virtual void onEndSolveStep(const AnalysisMethod & method); virtual void onDamageIteration(); virtual void onDamageUpdate(); virtual void onDump(); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: AKANTU_GET_MACRO(Name, name, const std::string &); AKANTU_GET_MACRO(Model, *model, const SolidMechanicsModel &) AKANTU_GET_MACRO(ID, Memory::getID(), const ID &); AKANTU_GET_MACRO(Rho, rho, Real); AKANTU_SET_MACRO(Rho, rho, Real); AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt); /// return the potential energy for the subset of elements contained by the material Real getPotentialEnergy(); /// return the potential energy for the provided element Real getPotentialEnergy(ElementType & type, UInt index); /// return the energy (identified by id) for the subset of elements contained by the material virtual Real getEnergy(std::string energy_id); /// return the energy (identified by id) for the provided element virtual Real getEnergy(std::string energy_id, ElementType type, UInt index); AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(ElementFilter, element_filter, UInt); AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(GradU, gradu, Real); AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Stress, stress, Real); AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(PotentialEnergy, potential_energy, Real); AKANTU_GET_MACRO(GradU, gradu, const ElementTypeMapArray &); AKANTU_GET_MACRO(Stress, stress, const ElementTypeMapArray &); AKANTU_GET_MACRO(ElementFilter, element_filter, const ElementTypeMapArray &); AKANTU_GET_MACRO(FEEngine, *fem, FEEngine &); bool isNonLocal() const { return is_non_local; } template const Array & getArray(const ID & id, const ElementType & type, const GhostType & ghost_type = _not_ghost) const; template Array & getArray(const ID & id, const ElementType & type, const GhostType & ghost_type = _not_ghost); template const InternalField & getInternal(const ID & id) const; template InternalField & getInternal(const ID & id); inline bool isInternal(const ID & id, const ElementKind & element_kind) const; virtual ElementTypeMap getInternalDataPerElem(const ID & id, - const ElementKind & element_kind, - const ID & fe_engine_id = "") const; + const ElementKind & element_kind, + const ID & fe_engine_id = "") const; bool isFiniteDeformation() const { return finite_deformation; } bool isInelasticDeformation() const { return inelastic_deformation; } template inline void setParam(const ID & param, T value); template inline const T & getParam(const ID & param) const; virtual void flattenInternal(const std::string & field_id, - ElementTypeMapArray & internal_flat, + ElementTypeMapArray & internal_flat, const GhostType ghost_type = _not_ghost, ElementKind element_kind = _ek_not_defined) const; protected: /// internal variation of the flatten function that is more flexible and can /// be used by inherited materials to change some behavior virtual void flattenInternalIntern(const std::string & field_id, - ElementTypeMapArray & internal_flat, - UInt spatial_dimension, - const GhostType ghost_type, - ElementKind element_kind, - const ElementTypeMapArray * element_filter = NULL, - const Mesh * mesh = NULL) const; + ElementTypeMapArray & internal_flat, + UInt spatial_dimension, + const GhostType ghost_type, + ElementKind element_kind, + const ElementTypeMapArray * element_filter = NULL, + const Mesh * mesh = NULL) const; protected: bool isInit() const { return is_init; } /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /// boolean to know if the material has been initialized bool is_init; std::map *> internal_vectors_real; std::map *> internal_vectors_uint; std::map *> internal_vectors_bool; protected: /// Link to the fem object in the model FEEngine * fem; /// Finite deformation bool finite_deformation; /// Finite deformation bool inelastic_deformation; /// material name std::string name; /// The model to witch the material belong SolidMechanicsModel * model; /// density : rho Real rho; /// spatial dimension UInt spatial_dimension; /// list of element handled by the material ElementTypeMapArray element_filter; /// stresses arrays ordered by element types InternalField stress; /// eigengrad_u arrays ordered by element types InternalField eigengradu; /// grad_u arrays ordered by element types InternalField gradu; /// Green Lagrange strain (Finite deformation) InternalField green_strain; /// Second Piola-Kirchhoff stress tensor arrays ordered by element types (Finite deformation) InternalField piola_kirchhoff_2; /// potential energy by element InternalField potential_energy; /// tell if using in non local mode or not bool is_non_local; /// tell if the material need the previous stress state bool use_previous_stress; /// tell if the material need the previous strain state bool use_previous_gradu; /// elemental field interpolation coordinates InternalField interpolation_inverse_coordinates; /// elemental field interpolation points InternalField interpolation_points_matrices; /// vector that contains the names of all the internals that need to /// be transferred when material interfaces move std::vector internals_to_transfer; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ #include "material_inline_impl.cc" /// standard output stream operator inline std::ostream & operator <<(std::ostream & stream, const Material & _this) { _this.printself(stream); return stream; } __END_AKANTU__ #include "internal_field_tmpl.hh" #include "random_internal_field_tmpl.hh" /* -------------------------------------------------------------------------- */ /* Auto loop */ /* -------------------------------------------------------------------------- */ - +/// This can be used to automatically write the loop on quadrature points in +/// functions such as computeStress. This macro in addition to write the loop +/// provides two tensors (matrices) sigma and grad_u #define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type) \ - Array::matrix_iterator gradu_it = \ + Array::matrix_iterator gradu_it = \ this->gradu(el_type, ghost_type).begin(this->spatial_dimension, \ - this->spatial_dimension); \ - Array::matrix_iterator gradu_end = \ + this->spatial_dimension); \ + Array::matrix_iterator gradu_end = \ this->gradu(el_type, ghost_type).end(this->spatial_dimension, \ - this->spatial_dimension); \ + this->spatial_dimension); \ \ this->stress(el_type, \ - ghost_type).resize(this->gradu(el_type, \ - ghost_type).getSize()); \ + ghost_type).resize(this->gradu(el_type, \ + ghost_type).getSize()); \ \ - Array::iterator< Matrix > stress_it = \ + Array::iterator< Matrix > stress_it = \ this->stress(el_type, ghost_type).begin(this->spatial_dimension, \ this->spatial_dimension); \ \ if(this->isFiniteDeformation()){ \ this->piola_kirchhoff_2(el_type, \ - ghost_type).resize(this->gradu(el_type, \ - ghost_type).getSize()); \ + ghost_type).resize(this->gradu(el_type, \ + ghost_type).getSize()); \ stress_it = \ this->piola_kirchhoff_2(el_type, \ - ghost_type).begin(this->spatial_dimension, \ - this->spatial_dimension); \ + ghost_type).begin(this->spatial_dimension, \ + this->spatial_dimension); \ } \ \ - for(;gradu_it != gradu_end; ++gradu_it, ++stress_it) { \ - Matrix & __attribute__((unused)) grad_u = *gradu_it; \ + for(;gradu_it != gradu_end; ++gradu_it, ++stress_it) { \ + Matrix & __attribute__((unused)) grad_u = *gradu_it; \ Matrix & __attribute__((unused)) sigma = *stress_it -#define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END \ - } \ +#define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END \ + } \ -#define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_mat) \ - Array::matrix_iterator gradu_it = \ +/// This can be used to automatically write the loop on quadrature points in +/// functions such as computeTangentModuli. This macro in addition to write the +/// loop provides two tensors (matrices) sigma_tensor, grad_u, and a matrix +/// where the elemental tangent moduli should be stored in Voigt Notation +#define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_mat) \ + Array::matrix_iterator gradu_it = \ this->gradu(el_type, ghost_type).begin(this->spatial_dimension, \ - this->spatial_dimension); \ - Array::matrix_iterator gradu_end = \ + this->spatial_dimension); \ + Array::matrix_iterator gradu_end = \ this->gradu(el_type, ghost_type).end(this->spatial_dimension, \ - this->spatial_dimension); \ - Array::matrix_iterator sigma_it = \ + this->spatial_dimension); \ + Array::matrix_iterator sigma_it = \ this->stress(el_type, ghost_type).begin(this->spatial_dimension, \ - this->spatial_dimension); \ - \ - tangent_mat.resize(this->gradu(el_type, ghost_type).getSize()); \ - \ - UInt tangent_size = \ + this->spatial_dimension); \ + \ + tangent_mat.resize(this->gradu(el_type, ghost_type).getSize()); \ + \ + UInt tangent_size = \ this->getTangentStiffnessVoigtSize(this->spatial_dimension); \ - Array::matrix_iterator tangent_it = \ - tangent_mat.begin(tangent_size, \ - tangent_size); \ - \ - for(;gradu_it != gradu_end; ++gradu_it, ++sigma_it, ++tangent_it) { \ - Matrix & __attribute__((unused)) grad_u = *gradu_it; \ - Matrix & __attribute__((unused)) sigma_tensor = *sigma_it; \ + Array::matrix_iterator tangent_it = \ + tangent_mat.begin(tangent_size, \ + tangent_size); \ + \ + for(;gradu_it != gradu_end; ++gradu_it, ++sigma_it, ++tangent_it) { \ + Matrix & __attribute__((unused)) grad_u = *gradu_it; \ + Matrix & __attribute__((unused)) sigma_tensor = *sigma_it; \ Matrix & tangent = *tangent_it -#define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END \ +#define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END \ } \ /* -------------------------------------------------------------------------- */ -#define INSTANTIATE_MATERIAL(mat_name) \ - template class mat_name<1>; \ - template class mat_name<2>; \ +#define INSTANTIATE_MATERIAL(mat_name) \ + template class mat_name<1>; \ + template class mat_name<2>; \ template class mat_name<3> #endif /* __AKANTU_MATERIAL_HH__ */ diff --git a/src/model/solid_mechanics/material_inline_impl.cc b/src/model/solid_mechanics/material_inline_impl.cc index 6c6c1f0b8..91681ed6b 100644 --- a/src/model/solid_mechanics/material_inline_impl.cc +++ b/src/model/solid_mechanics/material_inline_impl.cc @@ -1,354 +1,341 @@ /** * @file material_inline_impl.cc * * @author Marco Vocialta * @author Nicolas Richart * @author Daniel Pino Muñoz * * @date creation: Tue Jul 27 2010 * @date last modification: Tue Sep 16 2014 * * @brief Implementation of the inline functions of the class material * * @section LICENSE * * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ __END_AKANTU__ #include "solid_mechanics_model.hh" #include __BEGIN_AKANTU__ /* -------------------------------------------------------------------------- */ inline UInt Material::addElement(const ElementType & type, - UInt element, - const GhostType & ghost_type) { + UInt element, + const GhostType & ghost_type) { Array & el_filter = element_filter(type, ghost_type); el_filter.push_back(element); return el_filter.getSize()-1; } /* -------------------------------------------------------------------------- */ inline UInt Material::getTangentStiffnessVoigtSize(UInt dim) const { return (dim * (dim - 1) / 2 + dim); } /* -------------------------------------------------------------------------- */ inline UInt Material::getCauchyStressMatrixSize(UInt dim) const { return (dim * dim); } /* -------------------------------------------------------------------------- */ template inline void Material::gradUToF(const Matrix & grad_u, - Matrix & F) { + Matrix & F) { AKANTU_DEBUG_ASSERT(F.size() >= grad_u.size() && grad_u.size() == dim*dim, "The dimension of the tensor F should be greater or equal to the dimension of the tensor grad_u."); F.eye(); for (UInt i = 0; i < dim; ++i) for (UInt j = 0; j < dim; ++j) F(i, j) += grad_u(i, j); } /* -------------------------------------------------------------------------- */ template inline void Material::computeCauchyStressOnQuad(const Matrix & F, - const Matrix & piola, - Matrix & sigma, + const Matrix & piola, + Matrix & sigma, const Real & C33 ) const { Real J = F.det() * sqrt(C33); Matrix F_S(dim, dim); F_S.mul(F, piola); Real constant = J ? 1./J : 0; sigma.mul(F_S, F, constant); } /* -------------------------------------------------------------------------- */ inline void Material::rightCauchy(const Matrix & F, - Matrix & C) { + Matrix & C) { C.mul(F, F); } /* -------------------------------------------------------------------------- */ inline void Material::leftCauchy(const Matrix & F, - Matrix & B) { + Matrix & B) { B.mul(F, F); } /* -------------------------------------------------------------------------- */ template inline void Material::gradUToEpsilon(const Matrix & grad_u, - Matrix & epsilon) { + Matrix & epsilon) { for (UInt i = 0; i < dim; ++i) for (UInt j = 0; j < dim; ++j) epsilon(i, j) = 0.5*(grad_u(i, j) + grad_u(j, i)); } /* -------------------------------------------------------------------------- */ template inline void Material::gradUToGreenStrain(const Matrix & grad_u, - Matrix & epsilon) { + Matrix & epsilon) { epsilon.mul(grad_u, grad_u, .5); for (UInt i = 0; i < dim; ++i) for (UInt j = 0; j < dim; ++j) epsilon(i, j) += 0.5 * (grad_u(i, j) + grad_u(j, i)); } /* -------------------------------------------------------------------------- */ inline Real Material::stressToVonMises(const Matrix & stress) { // compute deviatoric stress UInt dim = stress.cols(); Matrix deviatoric_stress = Matrix::eye(dim, -1. * stress.trace() / 3.); for (UInt i = 0; i < dim; ++i) for (UInt j = 0; j < dim; ++j) deviatoric_stress(i,j) += stress(i,j); // return Von Mises stress return std::sqrt(3. * deviatoric_stress.doubleDot(deviatoric_stress) / 2.); } /* ---------------------------------------------------------------------------*/ template -inline void Material::SetCauchyStressArray(const Matrix & S_t, Matrix & Stress_vect) { - - AKANTU_DEBUG_IN(); - - Stress_vect.clear(); - - //UInt cauchy_matrix_size = getCauchyStressArraySize(dim); - - //see Finite ekement formulations for large deformation dynamic analysis, Bathe et al. IJNME vol 9, 1975, page 364 ^t\tau - - /* - * 1d: [ s11 ]' - * 2d: [ s11 s22 s12 ]' - * 3d: [ s11 s22 s33 s23 s13 s12 ] - */ - for (UInt i = 0; i < dim; ++i)//diagonal terms - Stress_vect(i, 0) = S_t(i, i); - - for (UInt i = 1; i < dim; ++i)// term s12 in 2D and terms s23 s13 in 3D - Stress_vect(dim+i-1, 0) = S_t(dim-i-1, dim-1); - - for (UInt i = 2; i < dim; ++i)//term s13 in 3D - Stress_vect(dim+i, 0) = S_t(0, 1); - - AKANTU_DEBUG_OUT(); +inline void Material::setCauchyStressArray(const Matrix & S_t, Matrix & sigma_voight) { + AKANTU_DEBUG_IN(); + sigma_voight.clear(); + //see Finite ekement formulations for large deformation dynamic analysis, Bathe et al. IJNME vol 9, 1975, page 364 ^t\tau + + /* + * 1d: [ s11 ]' + * 2d: [ s11 s22 s12 ]' + * 3d: [ s11 s22 s33 s23 s13 s12 ] + */ + for (UInt i = 0; i < dim; ++i)//diagonal terms + sigma_voight(i, 0) = S_t(i, i); + + for (UInt i = 1; i < dim; ++i)// term s12 in 2D and terms s23 s13 in 3D + sigma_voight(dim+i-1, 0) = S_t(dim-i-1, dim-1); + + for (UInt i = 2; i < dim; ++i)//term s13 in 3D + sigma_voight(dim+i, 0) = S_t(0, 1); + + AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ template -inline void Material::setCauchyStressMatrix(const Matrix & S_t, Matrix & Stress_matrix) { - - AKANTU_DEBUG_IN(); - - Stress_matrix.clear(); - - /// see Finite ekement formulations for large deformation dynamic analysis, - /// Bathe et al. IJNME vol 9, 1975, page 364 ^t\tau - - for (UInt i = 0; i < dim; ++i) { - for (UInt m = 0; m < dim; ++m) { - for (UInt n = 0; n < dim; ++n) { - Stress_matrix(i * dim + m, i * dim + n) = S_t(m, n); - } - } +inline void Material::setCauchyStressMatrix(const Matrix & S_t, Matrix & sigma) { + AKANTU_DEBUG_IN(); + + sigma.clear(); + + /// see Finite ekement formulations for large deformation dynamic analysis, + /// Bathe et al. IJNME vol 9, 1975, page 364 ^t\tau + for (UInt i = 0; i < dim; ++i) { + for (UInt m = 0; m < dim; ++m) { + for (UInt n = 0; n < dim; ++n) { + sigma(i * dim + m, i * dim + n) = S_t(m, n); + } } + } - //other terms from the diagonal - /*for (UInt i = 0; i < 3 - dim; ++i) { - Stress_matrix(dim * dim + i, dim * dim + i) = S_t(dim + i, dim + i); - }*/ - - - AKANTU_DEBUG_OUT(); + AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ inline Element Material::convertToLocalElement(const Element & global_element) const { UInt ge = global_element.element; #ifndef AKANTU_NDEBUG UInt model_mat_index = this->model->getMaterialByElement(global_element.type, - global_element.ghost_type)(ge); + global_element.ghost_type)(ge); UInt mat_index = this->model->getMaterialIndex(this->name); AKANTU_DEBUG_ASSERT(model_mat_index == mat_index, - "Conversion of a global element in a local element for the wrong material " - << this->name << std::endl); + "Conversion of a global element in a local element for the wrong material " + << this->name << std::endl); #endif UInt le = this->model->getMaterialLocalNumbering(global_element.type, - global_element.ghost_type)(ge); + global_element.ghost_type)(ge); Element tmp_quad(global_element.type, - le, - global_element.ghost_type, - global_element.kind); + le, + global_element.ghost_type, + global_element.kind); return tmp_quad; } /* -------------------------------------------------------------------------- */ inline Element Material::convertToGlobalElement(const Element & local_element) const { UInt le = local_element.element; UInt ge = this->element_filter(local_element.type, local_element.ghost_type)(le); Element tmp_quad(local_element.type, - ge, - local_element.ghost_type, - local_element.kind); + ge, + local_element.ghost_type, + local_element.kind); return tmp_quad; } /* -------------------------------------------------------------------------- */ inline QuadraturePoint Material::convertToLocalPoint(const QuadraturePoint & global_point) const { const FEEngine & fem = this->model->getFEEngine(); UInt nb_quad = fem.getNbQuadraturePoints(global_point.type); Element el = this->convertToLocalElement(static_cast(global_point)); QuadraturePoint tmp_quad(el, global_point.num_point, nb_quad); return tmp_quad; } /* -------------------------------------------------------------------------- */ inline QuadraturePoint Material::convertToGlobalPoint(const QuadraturePoint & local_point) const { const FEEngine & fem = this->model->getFEEngine(); UInt nb_quad = fem.getNbQuadraturePoints(local_point.type); Element el = this->convertToGlobalElement(static_cast(local_point)); QuadraturePoint tmp_quad(el, local_point.num_point, nb_quad); return tmp_quad; } /* -------------------------------------------------------------------------- */ inline UInt Material::getNbDataForElements(const Array & elements, - SynchronizationTag tag) const { + SynchronizationTag tag) const { if(tag == _gst_smm_stress) { return (this->isFiniteDeformation() ? 3 : 1) * spatial_dimension * spatial_dimension * sizeof(Real) * this->getModel().getNbQuadraturePoints(elements); } return 0; } /* -------------------------------------------------------------------------- */ inline void Material::packElementData(CommunicationBuffer & buffer, - const Array & elements, - SynchronizationTag tag) const { + const Array & elements, + SynchronizationTag tag) const { if(tag == _gst_smm_stress) { if(this->isFiniteDeformation()) { packElementDataHelper(piola_kirchhoff_2, buffer, elements); packElementDataHelper(gradu, buffer, elements); } packElementDataHelper(stress, buffer, elements); } } /* -------------------------------------------------------------------------- */ inline void Material::unpackElementData(CommunicationBuffer & buffer, - const Array & elements, - SynchronizationTag tag) { + const Array & elements, + SynchronizationTag tag) { if(tag == _gst_smm_stress) { if(this->isFiniteDeformation()) { unpackElementDataHelper(piola_kirchhoff_2, buffer, elements); unpackElementDataHelper(gradu, buffer, elements); } unpackElementDataHelper(stress, buffer, elements); } } /* -------------------------------------------------------------------------- */ template inline const T & Material::getParam(const ID & param) const { try { return get(param); } catch (...) { AKANTU_EXCEPTION("No parameter " << param << " in the material " << getID()); } } /* -------------------------------------------------------------------------- */ template inline void Material::setParam(const ID & param, T value) { try { set(param, value); } catch(...) { AKANTU_EXCEPTION("No parameter " << param << " in the material " << getID()); } updateInternalParameters(); } /* -------------------------------------------------------------------------- */ template inline void Material::packElementDataHelper(const ElementTypeMapArray & data_to_pack, - CommunicationBuffer & buffer, - const Array & elements, - const ID & fem_id) const { + CommunicationBuffer & buffer, + const Array & elements, + const ID & fem_id) const { DataAccessor::packElementalDataHelper(data_to_pack, buffer, elements, true, - model->getFEEngine(fem_id)); + model->getFEEngine(fem_id)); } /* -------------------------------------------------------------------------- */ template inline void Material::unpackElementDataHelper(ElementTypeMapArray & data_to_unpack, - CommunicationBuffer & buffer, - const Array & elements, - const ID & fem_id) { + CommunicationBuffer & buffer, + const Array & elements, + const ID & fem_id) { DataAccessor::unpackElementalDataHelper(data_to_unpack, buffer, elements, true, - model->getFEEngine(fem_id)); + model->getFEEngine(fem_id)); } /* -------------------------------------------------------------------------- */ template<> inline void Material::registerInternal(InternalField & vect) { internal_vectors_real[vect.getID()] = &vect; } template<> inline void Material::registerInternal(InternalField & vect) { internal_vectors_uint[vect.getID()] = &vect; } template<> inline void Material::registerInternal(InternalField & vect) { internal_vectors_bool[vect.getID()] = &vect; } /* -------------------------------------------------------------------------- */ template<> inline void Material::unregisterInternal(InternalField & vect) { internal_vectors_real.erase(vect.getID()); } template<> inline void Material::unregisterInternal(InternalField & vect) { internal_vectors_uint.erase(vect.getID()); } template<> inline void Material::unregisterInternal(InternalField & vect) { internal_vectors_bool.erase(vect.getID()); } /* -------------------------------------------------------------------------- */ inline bool Material::isInternal(const ID & id, const ElementKind & element_kind) const { std::map *>::const_iterator internal_array = internal_vectors_real.find(this->getID()+":"+id); if (internal_array == internal_vectors_real.end() || internal_array->second->getElementKind() != element_kind) return false; return true; }