diff --git a/test/test_model/test_solid_mechanics_model/test_contact/test_contact_rigid_no_friction/CMakeLists.txt b/test/test_model/test_solid_mechanics_model/test_contact/test_contact_rigid_no_friction/CMakeLists.txt index da0d8e61d..44e5f8db3 100644 --- a/test/test_model/test_solid_mechanics_model/test_contact/test_contact_rigid_no_friction/CMakeLists.txt +++ b/test/test_model/test_solid_mechanics_model/test_contact/test_contact_rigid_no_friction/CMakeLists.txt @@ -1,39 +1,39 @@ #=============================================================================== # @file CMakeLists.txt # @author David Kammer <david.kammer@epfl.ch> # @date Wed Jan 19 12:37:24 2011 # # @section LICENSE # # <insert lisence here> # # @section DESCRIPTION # #=============================================================================== #=============================================================================== add_mesh(test_squares_mesh squares.geo 2 1) register_test(test_contact_rigid_no_friction_triangle_3 test_contact_rigid_no_friction_triangle_3.cc) add_dependencies(test_contact_rigid_no_friction_triangle_3 test_squares_mesh) #=============================================================================== add_mesh(test_cubes_mesh cubes.geo 3 1) register_test(test_contact_rigid_no_friction_tetrahedron_4 test_contact_rigid_no_friction_tetrahedron_4.cc) add_dependencies(test_contact_rigid_no_friction_tetrahedron_4 test_cubes_mesh) #=============================================================================== -add_mesh(test_hertz_2d_mesh hertz.geo 2 1) +add_mesh(test_hertz_2d_mesh hertz_2d.geo 2 1) register_test(test_contact_rigid_no_friction_hertz_2d test_contact_rigid_no_friction_hertz_2d.cc) add_dependencies(test_contact_rigid_no_friction_hertz_2d test_hertz_2d_mesh) #=============================================================================== configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/material.dat ${CMAKE_CURRENT_BINARY_DIR}/material.dat COPYONLY ) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/paraview) diff --git a/test/test_model/test_solid_mechanics_model/test_contact/test_contact_rigid_no_friction/hertz_2d.geo b/test/test_model/test_solid_mechanics_model/test_contact/test_contact_rigid_no_friction/hertz_2d.geo new file mode 100644 index 000000000..bcd47459c --- /dev/null +++ b/test/test_model/test_solid_mechanics_model/test_contact/test_contact_rigid_no_friction/hertz_2d.geo @@ -0,0 +1,27 @@ +h_contact = 0.01; +h_sphere = 0.1; +h_plate = 0.05; + +Point(1) = {0, 0, 0, h_sphere}; +Point(2) = {1, 0, 0, h_sphere}; +Point(3) = {0, -1, 0, h_contact}; + +Point(4) = {-0.25, -1.01, 0, h_plate}; +Point(5) = {-0.25, -1.21, 0, h_plate}; +Point(6) = {1.25, -1.21, 0, h_plate}; +Point(7) = {1.25, -1.01, 0, h_plate}; + +Circle(1) = {3, 1, 2}; +Line(2) = {2, 1}; +Line(3) = {1, 3}; + +Line(4) = {4, 5}; +Line(5) = {5, 6}; +Line(6) = {6, 7}; +Line(7) = {7, 4}; + +Line Loop(9) = {1, 2, 3}; +Plane Surface(9) = {9}; + +Line Loop(11) = {7, 4, 5, 6}; +Plane Surface(11) = {11}; diff --git a/test/test_model/test_solid_mechanics_model/test_contact/test_contact_rigid_no_friction/test_contact_rigid_no_friction_hertz_2d.cc b/test/test_model/test_solid_mechanics_model/test_contact/test_contact_rigid_no_friction/test_contact_rigid_no_friction_hertz_2d.cc new file mode 100644 index 000000000..b4ab52239 --- /dev/null +++ b/test/test_model/test_solid_mechanics_model/test_contact/test_contact_rigid_no_friction/test_contact_rigid_no_friction_hertz_2d.cc @@ -0,0 +1,222 @@ +/** + * @file test_contact_regular_grid.cc + * @author David Kammer <david.kammer@epfl.ch> + * @date Wed Jan 19 15:04:42 2011 + * + * @brief test contact search for 2d hertz in explicit + * + * @section LICENSE + * + * <insert license here> + * + */ + +/* -------------------------------------------------------------------------- */ + +#include "aka_common.hh" +#include "mesh.hh" +#include "mesh_io.hh" +#include "mesh_io_msh.hh" +#include "mesh_utils.hh" +#include "solid_mechanics_model.hh" +#include "material.hh" +#include "contact.hh" +#include "contact_neighbor_structure.hh" +#include "regular_grid_neighbor_structure.hh" +#include "contact_search.hh" +#include "contact_search_3d_explicit.hh" + +#ifdef AKANTU_USE_IOHELPER +# include "io_helper.h" +#endif //AKANTU_USE_IOHELPER + +using namespace akantu; + +int main(int argc, char *argv[]) +{ + int dim = 2; + const ElementType element_type = _triangle_3; + const UInt paraview_type = TRIANGLE1; + + UInt max_steps = 200000; + UInt imposing_steps = 100000; + Real max_displacement = -0.1; + + /// load mesh + Mesh my_mesh(dim); + MeshIOMSH mesh_io; + mesh_io.read("hertz_2d.msh", my_mesh); + + /// build facet connectivity and surface id + MeshUtils::buildFacets(my_mesh,1,0); + MeshUtils::buildSurfaceID(my_mesh); + + UInt nb_nodes = my_mesh.getNbNodes(); + + /// declaration of model + SolidMechanicsModel my_model(my_mesh); + /// model initialization + my_model.initVectors(); + // initialize the vectors + memset(my_model.getForce().values, 0, dim*nb_nodes*sizeof(Real)); + memset(my_model.getVelocity().values, 0, dim*nb_nodes*sizeof(Real)); + memset(my_model.getAcceleration().values, 0, dim*nb_nodes*sizeof(Real)); + memset(my_model.getDisplacement().values, 0, dim*nb_nodes*sizeof(Real)); + memset(my_model.getBoundary().values, false, dim*nb_nodes*sizeof(bool)); + + my_model.readMaterials("material.dat"); + my_model.initMaterials(); + my_model.initModel(); + + UInt nb_element = my_model.getFEM().getMesh().getNbElement(element_type); + + Real time_step = my_model.getStableTimeStep(); + my_model.setTimeStep(time_step/10.); + + my_model.assembleMassLumped(); + + /// contact declaration + Contact * my_contact = Contact::newContact(my_model, + _ct_rigid_no_fric, + _cst_3d_expli, + _cnst_regular_grid); + + my_contact->initContact(false); + + Surface master = 1; + my_contact->addMasterSurface(master); + + // const_cast<RegularGridNeighborStructure<2> &>(my_contact->getContactSearch().getContactNeighborStructure(master)).setGridSpacing(0.15, 0); + const RegularGridNeighborStructure<2> & my_rgns = dynamic_cast<const RegularGridNeighborStructure<2> &>(my_contact->getContactSearch().getContactNeighborStructure(master)); + const_cast<RegularGridNeighborStructure<2>&>(my_rgns).setGridSpacing(0.075, 0); + const_cast<RegularGridNeighborStructure<2>&>(my_rgns).setGridSpacing(0.075, 1); + + my_model.updateCurrentPosition(); // neighbor structure uses current position for init + my_contact->initNeighborStructure(master); + my_contact->initSearch(); // does nothing so far + + // boundary conditions + Surface impactor = 0; + Vector<UInt> * top_nodes = new Vector<UInt>(0, 1); + UInt middle_point; + Real * coordinates = my_mesh.getNodes().values; + Real * displacement = my_model.getDisplacement().values; + bool * boundary = my_model.getBoundary().values; + UInt * surface_to_nodes_offset = my_contact->getSurfaceToNodesOffset().values; + UInt * surface_to_nodes = my_contact->getSurfaceToNodes().values; + // symetry boundary conditions + for(UInt n = surface_to_nodes_offset[impactor]; n < surface_to_nodes_offset[impactor+1]; ++n) { + UInt node = surface_to_nodes[n]; + Real x_coord = coordinates[node*dim]; + Real y_coord = coordinates[node*dim + 1]; + if (x_coord < 0.00001) + boundary[node*dim] = true; + if (y_coord > -0.00001) { + boundary[node*dim + 1] = true; + top_nodes->push_back(node); + } + if (x_coord < 0.00001 && y_coord > -0.00001) + middle_point = node; + } + // ground boundary conditions + for(UInt n = surface_to_nodes_offset[master]; n < surface_to_nodes_offset[master+1]; ++n) { + UInt node = surface_to_nodes[n]; + Real y_coord = coordinates[node*dim + 1]; + if (y_coord < -1.2) + boundary[node*dim] = true; + boundary[node*dim + 1] = true; + } + UInt * top_nodes_val = top_nodes->values; + +#ifdef AKANTU_USE_IOHELPER + /// initialize the paraview output + DumperParaview dumper; + dumper.SetMode(TEXT); + dumper.SetPoints(my_model.getFEM().getMesh().getNodes().values, dim, nb_nodes, "coordinates"); + dumper.SetConnectivity((int *)my_model.getFEM().getMesh().getConnectivity(element_type).values, + paraview_type, nb_element, C_MODE); + dumper.AddNodeDataField(my_model.getDisplacement().values, + dim, "displacements"); + dumper.AddNodeDataField(my_model.getVelocity().values, dim, "velocity"); + dumper.AddNodeDataField(my_model.getResidual().values, dim, "force"); + dumper.AddNodeDataField(my_model.getForce().values, dim, "applied_force"); + dumper.AddElemDataField(my_model.getMaterial(0).getStrain(element_type).values, dim*dim, "strain"); + dumper.AddElemDataField(my_model.getMaterial(0).getStress(element_type).values, dim*dim, "stress"); + dumper.SetEmbeddedValue("displacements", 1); + dumper.SetEmbeddedValue("applied_force", 1); + dumper.SetPrefix("paraview/"); + dumper.Init(); + dumper.Dump(); +#endif //AKANTU_USE_IOHELPER + + std::ofstream hertz; + hertz.open("hertz_2d.csv"); + hertz << "%id,ftop,fcont,zone" << std::endl; + + + /* ------------------------------------------------------------------------ */ + /* Main loop */ + /* ------------------------------------------------------------------------ */ + for(UInt s = 1; s <= max_steps; ++s) { + + if(s % 10 == 0) std::cout << "passing step " << s << "/" << max_steps << std::endl; + + if(s <= imposing_steps) { + Real current_displacement = max_displacement/(static_cast<Real>(imposing_steps))*s; + for(UInt n=0; n<top_nodes->getSize(); ++n) { + UInt node = top_nodes_val[n]; + displacement[node*dim + 1] = current_displacement; + } + } + + my_model.explicitPred(); + + my_model.updateCurrentPosition(); + + /// compute the penetration list + PenetrationList * my_penetration_list = new PenetrationList(); + const_cast<ContactSearch &>(my_contact->getContactSearch()).findPenetration(master, *my_penetration_list); + UInt nb_nodes_pen = my_penetration_list->penetrating_nodes.getSize(); + Vector<UInt> pen_nodes = my_penetration_list->penetrating_nodes; + UInt * pen_nodes_val = pen_nodes.values; + + my_contact->solveContact(); + + my_model.updateResidual(false); + my_model.updateAcceleration(); + my_model.explicitCorr(); + + Real * residual = my_model.getResidual().values; + Real top_force = 0.; + for(UInt n=0; n<top_nodes->getSize(); ++n) { + UInt node = top_nodes_val[n]; + top_force += residual[node*dim + 1]; + } + my_model.updateCurrentPosition(); + Real * current_position = my_model.getCurrentPosition().values; + Real contact_force = 0.; + Real contact_zone = 0.; + for (UInt i = 0; i < nb_nodes_pen; ++i) { + UInt node = pen_nodes_val[i]; + contact_force += residual[node*dim + 1]; + contact_zone = std::max(contact_zone, current_position[node*dim]); + } + delete my_penetration_list; + + hertz << s << "," << top_force << "," << contact_force << "," << contact_zone << std::endl; + + + +#ifdef AKANTU_USE_IOHELPER + if(s % 100 == 0) dumper.Dump(); +#endif //AKANTU_USE_IOHELPER + } + + hertz.close(); + + delete my_contact; + + finalize(); + + return EXIT_SUCCESS; +}