diff --git a/test/test_io/test_dumper/CMakeLists.txt b/test/test_io/test_dumper/CMakeLists.txt index de73bfa4c..29ad33051 100644 --- a/test/test_io/test_dumper/CMakeLists.txt +++ b/test/test_io/test_dumper/CMakeLists.txt @@ -1,52 +1,52 @@ #=============================================================================== # @file CMakeLists.txt # # @author David Simon Kammer # # @date creation: Tue Sep 02 2014 # @date last modification: Tue Sep 02 2014 # # @brief configuration for tests # # @section LICENSE # # Copyright (©) 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 . # # @section DESCRIPTION # #=============================================================================== register_test(test_dumper SOURCES test_dumper.cc FILES_TO_COPY input_file.dat test_dumper.msh DIRECTORIES_TO_CREATE paraview PACKAGE iohelper ) -register_test(swiss_train - SOURCES swiss_train.cc +register_test(example_dumper_low_level + SOURCES example_dumper_low_level.cc FILES_TO_COPY swiss_train.msh DIRECTORIES_TO_CREATE paraview PACKAGE iohelper ) register_test(example_dumpable_interface SOURCES example_dumpable_interface.cc FILES_TO_COPY swiss_train.msh DIRECTORIES_TO_CREATE paraview PACKAGE iohelper ) diff --git a/test/test_io/test_dumper/example_dumpable_interface.cc b/test/test_io/test_dumper/example_dumpable_interface.cc index a4a707d7e..8ee8de93f 100644 --- a/test/test_io/test_dumper/example_dumpable_interface.cc +++ b/test/test_io/test_dumper/example_dumpable_interface.cc @@ -1,165 +1,181 @@ /** * @file example_dumpable_interface.cc * @author Fabian Barras * @date Thu Jul 2 14:34:41 2015 * - * @brief Example of IOHelper dumper advanced usage + * @brief Example of dumper::Dumpable interface. * * @section LICENSE * * Copyright (©) 2010-2011 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 #include #include /* -------------------------------------------------------------------------- */ #include "aka_common.hh" #include "mesh.hh" #include "element_group.hh" #include "mesh_io.hh" #include "mesh_io_msh.hh" #include "mesh_utils.hh" #include "dumper_paraview.hh" #include "locomotive.hh" #define PI 3.141592653589 /* -------------------------------------------------------------------------- */ using namespace akantu; int main(int argc, char *argv[]) { - /// In this example, we + /*In this example, we present dumper::Dumpable which is an interface + for other classes who want to dump themselves. + Several classes of Akantu inheritate from Dumpable (Model, Mesh, ...). + In this example we reproduce the same tasks as example_dumper_low_level.cc + using this time Dumpable interface inherted by Mesh, NodeGroup and ElementGroup. + It is then advised to read first example_dumper_low_level.cc.*/ + initialize(argc, argv); - - /// To start let us load the swiss train mesh with its mesh data + + /// To start let us load the swiss train mesh and its mesh data information. UInt spatial_dimension = 2; Mesh mesh(spatial_dimension); mesh.read("swiss_train.msh"); mesh.createGroupsFromMeshData("physical_names"); /* swiss_train.msh has the following physical groups that can be viewed with GMSH: "$MeshFormat 2.2 0 8 $EndMeshFormat $PhysicalNames 6 2 1 "rouge" 2 2 "blanc" 2 3 "lwheel_1" 2 4 "lwheel_2" 2 5 "rwheel_2" 2 6 "rwheel_1" $EndPhysicalNames ..." */ - /// Create grouping nodes and elements belonging to train wheels (=four mesh data) - NodeGroup wheels_nodes("wheels_nodes", mesh); + /// Grouping nodes and elements belonging to train wheels (=four mesh data). + NodeGroup & wheels_nodes = mesh.createNodeGroup("wheels_nodes"); wheels_nodes.append(mesh.getElementGroup("lwheel_1").getNodeGroup()); wheels_nodes.append(mesh.getElementGroup("lwheel_2").getNodeGroup()); wheels_nodes.append(mesh.getElementGroup("rwheel_1").getNodeGroup()); wheels_nodes.append(mesh.getElementGroup("rwheel_2").getNodeGroup()); ElementGroup & wheels_elements = mesh.createElementGroup("wheels_elements", spatial_dimension, wheels_nodes); wheels_elements.append(mesh.getElementGroup("lwheel_1")); wheels_elements.append(mesh.getElementGroup("lwheel_2")); wheels_elements.append(mesh.getElementGroup("rwheel_1")); wheels_elements.append(mesh.getElementGroup("rwheel_2")); + /// Create dumper for the complete mesh and register it as default dumper. DumperParaview dumper("train", "paraview/dumpable", false); mesh.registerExternalDumper(dumper, "train", true); mesh.addDumpMesh(mesh); - mesh.registerExternalDumper(mesh.getGroupDumper("paraview_wheels_elements", "wheels_elements"),"wheels_elements"); + /// The dumper for the filtered mesh can be directly taken from the ElementGroup + /// and then registered as "wheels_elements" dumper. + DumperIOHelper & wheels = mesh.getGroupDumper("paraview_wheels_elements", "wheels_elements"); + mesh.registerExternalDumper(wheels,"wheels_elements"); mesh.setDirectoryToDumper("wheels_elements","paraview/dumpable"); Array & node = mesh.getNodes(); UInt nb_nodes = mesh.getNbNodes(); + /// This time 2D Array is created and a padding size of 3 is passed to NodalField + /// in order to warp train deformation on Paraview. Array * displacement = new Array(nb_nodes,spatial_dimension); UInt padding_size = 3; + /// The colour ElementTypeMapArray is directly attached to the Mesh object + /// to simplify the creation of dumper::Field. ElementTypeMapArray & colour = mesh.registerData("colour"); mesh.initElementTypeMapArray(colour, 1, spatial_dimension, false, _ek_regular, true); + /// The creation of dumper::Field is completely handled by Dumpable interface. + /// The group name allows to create filter fields or standard fields if "all" is passed. mesh.addDumpFieldExternal("displacement", mesh.createNodalField(displacement, "all",padding_size)); mesh.addDumpFieldExternal("color", mesh.createFieldFromAttachedData("colour", "all", _ek_regular)); mesh.addDumpFieldExternalToDumper("wheels_elements", "displacement", mesh.createNodalField(displacement, "wheels_elements",padding_size)); mesh.addDumpFieldExternalToDumper("wheels_elements", "colour", mesh.createFieldFromAttachedData("colour", "wheels_elements", _ek_regular)); - /// Fill the ElementTypeMapArray colour according to mesh data information + /// Fill the ElementTypeMapArray colour. ElementTypeMapArray * phys_data = &(mesh.getData("physical_names")); Array & txt_colour = (*phys_data)(_triangle_3); Array & id_colour = (colour)(_triangle_3); for (UInt i = 0; i < txt_colour.getSize(); ++i) { std::string phy_name = txt_colour[i]; if (phy_name == "rouge") id_colour[i] = 3; else if (phy_name == "blanc"||phy_name == "lwheel_1"||phy_name == "rwheel_1") id_colour[i] = 2; else id_colour[i] = 1; } - /// Apply displacement and wheels rotation + /// Apply displacement and wheels rotation. Real tot_displacement = 50.; Real radius = 1.; UInt nb_steps = 500; Real theta = tot_displacement/radius; Array l_center(spatial_dimension); Array r_center(spatial_dimension); const Array & lnode_1 = (mesh.getElementGroup("lwheel_1")).getNodes(); const Array & lnode_2 = (mesh.getElementGroup("lwheel_2")).getNodes(); const Array & rnode_1 = (mesh.getElementGroup("rwheel_1")).getNodes(); const Array & rnode_2 = (mesh.getElementGroup("rwheel_2")).getNodes(); for (UInt i = 0; i < spatial_dimension; ++i) { l_center(i) = node(14,i); r_center(i) = node(2,i); } for (UInt i = 0; i < nb_steps; ++i) { displacement->clear(); Real angle = (Real)i / (Real)nb_steps * theta; applyRotation(l_center, angle, node, displacement, lnode_1); applyRotation(l_center, angle, node, displacement, lnode_2); applyRotation(r_center, angle, node, displacement, rnode_1); applyRotation(r_center, angle, node, displacement, rnode_2); for (UInt j = 0; j < nb_nodes; ++j) { (*displacement)(j,0) += (Real)i / (Real)nb_steps *tot_displacement; } - /// Results are output after each moving steps for main and wheel dumpers. + /// Dump call is finally made through Dumpable interface. mesh.dump(); mesh.dump("wheels_elements"); } return 0; } diff --git a/test/test_io/test_dumper/swiss_train.cc b/test/test_io/test_dumper/example_dumper_low_level.cc similarity index 79% rename from test/test_io/test_dumper/swiss_train.cc rename to test/test_io/test_dumper/example_dumper_low_level.cc index 55ec57568..61c5337f4 100644 --- a/test/test_io/test_dumper/swiss_train.cc +++ b/test/test_io/test_dumper/example_dumper_low_level.cc @@ -1,197 +1,205 @@ /** - * @file swiss_train.cc + * @file example_dumper_low_level.cc * @author Fabian Barras * @date Thu Jul 2 14:34:41 2015 * - * @brief Example of IOHelper dumper advanced usage + * @brief Example of dumper::DumperIOHelper low-level methods. * * @section LICENSE * * Copyright (©) 2010-2011 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 #include #include /* -------------------------------------------------------------------------- */ #include "aka_common.hh" #include "mesh.hh" #include "element_group.hh" #include "mesh_io.hh" #include "mesh_io_msh.hh" #include "mesh_utils.hh" #include "dumper_paraview.hh" #include "dumper_elemental_field.hh" #include "dumper_nodal_field.hh" #include "locomotive.hh" #define PI 3.141592653589 /* -------------------------------------------------------------------------- */ using namespace akantu; int main(int argc, char *argv[]) { - /// This example aims at illustrating how to manipulate low-level methods of DumperIOHelper. - /// The aims is to visualize a colorized moving train with Paraview + /* This example aims at illustrating how to manipulate low-level methods of DumperIOHelper. + The aims is to visualize a colorized moving train with Paraview */ + initialize(argc, argv); - /// To start let us load the swiss train mesh with its mesh data + /// To start let us load the swiss train mesh and its mesh data information. + /// We aknowledge here a weel-known swiss industry for mesh donation. UInt spatial_dimension = 2; Mesh mesh(spatial_dimension); mesh.read("swiss_train.msh"); mesh.createGroupsFromMeshData("physical_names"); /* swiss_train.msh has the following physical groups that can be viewed with GMSH: "$MeshFormat 2.2 0 8 $EndMeshFormat $PhysicalNames 6 2 1 "rouge" 2 2 "blanc" 2 3 "lwheel_1" 2 4 "lwheel_2" 2 5 "rwheel_2" 2 6 "rwheel_1" $EndPhysicalNames ..." */ - /// Creation of two dumper paraview. One for the complete mesh, one for a filtered mesh - DumperParaview dumper("train", "./paraview", false); - DumperParaview wheels("wheels", "./paraview", false); + /// Creation of two DumperParaview. One for full mesh, one for a filtered mesh. + DumperParaview dumper("train", "./paraview/dumper", false); + DumperParaview wheels("wheels", "./paraview/dumper", false); - /// Register the entire mesh + /// Register the full mesh dumper.registerMesh(mesh); - /// Create grouping nodes and elements belonging to train wheels (=four mesh data) - NodeGroup wheels_nodes("wheels_nodes", mesh); + /// Grouping nodes and elements belonging to train wheels (=four mesh data) + NodeGroup & wheels_nodes = mesh.createNodeGroup("wheels_nodes"); wheels_nodes.append(mesh.getElementGroup("lwheel_1").getNodeGroup()); wheels_nodes.append(mesh.getElementGroup("lwheel_2").getNodeGroup()); wheels_nodes.append(mesh.getElementGroup("rwheel_1").getNodeGroup()); wheels_nodes.append(mesh.getElementGroup("rwheel_2").getNodeGroup()); - ElementGroup wheels_elements("wheels_elements", mesh, wheels_nodes); + + ElementGroup & wheels_elements = mesh.createElementGroup("wheels_elements", spatial_dimension, wheels_nodes); wheels_elements.append(mesh.getElementGroup("lwheel_1")); wheels_elements.append(mesh.getElementGroup("lwheel_2")); wheels_elements.append(mesh.getElementGroup("rwheel_1")); wheels_elements.append(mesh.getElementGroup("rwheel_2")); /// Register a filtered mesh limited to nodes and elements from wheels groups wheels.registerFilteredMesh(mesh, wheels_elements.getElements(), wheels_elements.getNodes()); + /// Generate an output file of the two mesh registered. dumper.dump(); wheels.dump(); /// At this stage no fields are attached to the two meshes. /// To do so, a dumper::Field object has to be created. /// Several types of dumper::Field exist. In this example we present two of them. /// NodalField to describe nodal displacements of our train. /// ElementalField handling the color of our different part. Array & node = mesh.getNodes(); UInt nb_nodes = mesh.getNbNodes(); - /// NodalField are constructed with an Array + /// NodalField are constructed with an Array. + /* Note that this Array is constructed with three components + in order to warp train deformation on Paraview. + A more appropriate way to do this is to set a padding in the NodalField + (See example_dumpable_interface.cc.) */ Array * displacement = new Array(nb_nodes,3); dumper::Field * displ = new dumper::NodalField(*displacement); - /// ElementalField are constructed with an ElementTypeMapArray + /// ElementalField are constructed with an ElementTypeMapArray. ElementTypeMapArray colour; mesh.initElementTypeMapArray(colour, 1, spatial_dimension, false, _ek_regular, true); dumper::Field * color = new dumper::ElementalField(colour); - /// Register the freshly created fields to our dumper + /// Register the freshly created fields to our dumper. dumper.registerField("displacement", displ); dumper.registerField("colour", color); - /// Fields have to be filtered at registration to dumper wheels + /// For the dumper wheels, fields have to be filtered at registration. /// Filter NodalField can be simply registered by adding an Array listing filtered nodes. wheels.registerField("displacement", new dumper::NodalField(*displacement,0,0,&(wheels_elements.getNodes()))); /// For ElementalField, an ElementTypeMapArrayFilter has to be created. const ElementTypeMapArray & elemental_filter = wheels_elements.getElements(); ElementTypeMapArrayFilter * filter = new ElementTypeMapArrayFilter(colour,elemental_filter); wheels.registerField("colour", new dumper::ElementalField(*filter)); - ///Now that are dumper are created and the two fields are associated, let's paint and move the train! + ///Now that our dumpers are created and the two fields are associated, let's paint and move the train! - /// Fill the ElementTypeMapArray colour according to mesh data information + /// Fill the ElementTypeMapArray colour according to mesh data information. ElementTypeMapArray * phys_data = &(mesh.getData("physical_names")); Array & txt_colour = (*phys_data)(_triangle_3); Array & id_colour = (colour)(_triangle_3); for (UInt i = 0; i < txt_colour.getSize(); ++i) { std::string phy_name = txt_colour[i]; if (phy_name == "rouge") id_colour[i] = 3; else if (phy_name == "blanc"||phy_name == "lwheel_1"||phy_name == "rwheel_1") id_colour[i] = 2; else id_colour[i] = 1; } - /// Apply displacement and wheels rotation + /// Apply displacement and wheels rotation. Real tot_displacement = 50.; Real radius = 1.; UInt nb_steps = 500; Real theta = tot_displacement/radius; Array l_center(spatial_dimension); Array r_center(spatial_dimension); const Array & lnode_1 = (mesh.getElementGroup("lwheel_1")).getNodes(); const Array & lnode_2 = (mesh.getElementGroup("lwheel_2")).getNodes(); const Array & rnode_1 = (mesh.getElementGroup("rwheel_1")).getNodes(); const Array & rnode_2 = (mesh.getElementGroup("rwheel_2")).getNodes(); for (UInt i = 0; i < spatial_dimension; ++i) { l_center(i) = node(14,i); r_center(i) = node(2,i); } for (UInt i = 0; i < nb_steps; ++i) { displacement->clear(); Real angle = (Real)i / (Real)nb_steps * theta; applyRotation(l_center, angle, node, displacement, lnode_1); applyRotation(l_center, angle, node, displacement, lnode_2); applyRotation(r_center, angle, node, displacement, rnode_1); applyRotation(r_center, angle, node, displacement, rnode_2); for (UInt j = 0; j < nb_nodes; ++j) { (*displacement)(j,0) += (Real)i / (Real)nb_steps *tot_displacement; } - /// Results are output after each moving steps for main and wheel dumpers. + /// Output results after each moving steps for main and wheel dumpers. dumper.dump(); wheels.dump(); } return 0; }