diff --git a/python/swig/aka_array.i b/python/swig/aka_array.i index 117f31eac..a8acdf2ec 100644 --- a/python/swig/aka_array.i +++ b/python/swig/aka_array.i @@ -1,126 +1,126 @@ %{ #define SWIG_FILE_WITH_INIT #include "aka_array.hh" %} %include "typemaps.i" namespace akantu { %ignore Array::operator=; %ignore Array::operator[]; %ignore Array::operator(); %ignore Array::set; %ignore Array::begin; %ignore Array::end; %ignore Array::begin_reinterpret; %ignore Array::end_reinterpret; }; %include "aka_array.hh" namespace akantu { %template(RArray) Array; %template(UArray) Array; %template(BArray) Array; } %include "numpy.i" %init %{ import_array(); %} %define %akantu_array_typemaps(DATA_TYPE, DATA_TYPECODE) %typemap(out, fragment="NumPy_Fragments") (akantu::Array< DATA_TYPE > &) { npy_intp dims[2] = {$1->getSize(), $1->getNbComponent()}; PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, $1->storage()); PyArrayObject* array = (PyArrayObject*) obj; if (!array) SWIG_fail; $result = SWIG_Python_AppendOutput($result, obj); } %enddef %akantu_array_typemaps(double, NPY_DOUBLE) %akantu_array_typemaps(float, NPY_FLOAT ) %akantu_array_typemaps(unsigned int, NPY_UINT ) %typemap(out, fragment="NumPy_Fragments") (akantu::Array< bool > &) { npy_intp dims[2] = {$1->getSize(), $1->getNbComponent()}; int data_typecode = NPY_NOTYPE; size_t s = sizeof(bool); switch(s) { case 1: data_typecode = NPY_BOOL; break; case 2: data_typecode = NPY_UINT8; break; case 4: data_typecode = NPY_UINT16; break; case 8: data_typecode = NPY_UINT32; break; } PyObject* obj = PyArray_SimpleNewFromData(2, dims, data_typecode, $1->storage()); PyArrayObject* array = (PyArrayObject*) obj; if (!array) SWIG_fail; $result = SWIG_Python_AppendOutput($result, obj); } %inline %{ namespace akantu{ template class ArrayForPython : public Array{ public: ArrayForPython(T * wrapped_memory, UInt size = 0, UInt nb_component = 1, const ID & id = "") : Array(0,nb_component,id){ this->values = wrapped_memory; this->size = size; }; ~ArrayForPython(){ this->values = NULL; }; void resize(UInt new_size){ AKANTU_DEBUG_ASSERT(this->size == new_size,"cannot resize a temporary vector"); } }; } %} namespace akantu { -%template(ArrayForPythonReal) ArrayForPython; +%template(ArrayForPythonReal) ArrayForPython; } %typemap(in) akantu::Array & { if (!PyArray_Check($input)) { AKANTU_EXCEPTION("incompatible input which is not a numpy"); } else { PyArray_Descr * numpy_type = (PyArray_Descr*)PyArray_DESCR((PyArrayObject*)$input); if (numpy_type->kind != 'f') throw; UInt _n = PyArray_NDIM((PyArrayObject*)$input); if (_n != 2) AKANTU_EXCEPTION("incompatible numpy dimension " << _n); npy_intp * ndims = PyArray_DIMS((PyArrayObject*)$input); akantu::UInt sz = ndims[0]; akantu::UInt nb_components = ndims[1]; PyArrayIterObject *iter = (PyArrayIterObject *)PyArray_IterNew($input); if (iter == NULL) { AKANTU_EXCEPTION("Python internal error"); // PyErr_Print(); } $1 = new akantu::ArrayForPython((double*)(iter->dataptr),sz,nb_components,"tmp_array_for_python"); } } diff --git a/python/swig/aka_common.i b/python/swig/aka_common.i index fdd84e385..5ff11d227 100644 --- a/python/swig/aka_common.i +++ b/python/swig/aka_common.i @@ -1,66 +1,131 @@ %{ #include "aka_common.hh" + #include "aka_csr.hh" + #include "element.hh" %} namespace akantu { %ignore getStaticParser; %ignore getUserParser; %ignore initialize(int & argc, char ** & argv); %ignore initialize(const std::string & input_file, int & argc, char ** & argv); extern const Array empty_filter; } %typemap(in) (int argc, char *argv[]) { int i; if (!PyList_Check($input)) { PyErr_SetString(PyExc_ValueError, "Expecting a list"); return NULL; } $1 = PyList_Size($input); $2 = (char **) malloc(($1+1)*sizeof(char *)); for (i = 0; i < $1; i++) { PyObject *s = PyList_GetItem($input,i); if (!PyString_Check(s)) { free($2); PyErr_SetString(PyExc_ValueError, "List items must be strings"); return NULL; } $2[i] = PyString_AsString(s); } $2[i] = 0; } %typemap(freearg) (int argc, char *argv[]) { if ($2) free($2); } %inline %{ namespace akantu { void initialize(const std::string & input_file) { int argc = 0; char ** argv = NULL; initialize(input_file, argc, argv); } void initialize() { int argc = 0; char ** argv = NULL; initialize(argc, argv); } void _initializeWithArgv(const std::string & input_file, int argc, char *argv[]) { initialize(input_file, argc, argv); } } %} %pythoncode %{ import sys as _aka_sys def initializeWithArgv(input_file): _initializeWithArgv(input_file, _aka_sys.argv) %} %include "aka_common.hh" %include "aka_element_classes_info.hh" +%include "element.hh" + +%inline %{ +namespace akantu{ + template + class CSRIterator{ + + public: + CSRIterator(CSR & csr,UInt row) { + this->it = csr.begin(row); + this->end = csr.end(row); + }; + + ~CSRIterator(){ + }; + + T & __next_cpp(){ + if (this->it == this->end) AKANTU_SILENT_EXCEPTION("StopIteration"); + T & ref = *(this->it); + ++this->it; + return ref; + } + + private: + + typename CSR::iterator it; + typename CSR::iterator end; + }; +} +%} + +%extend akantu::CSRIterator +{ +%insert("python") %{ + def __iter__(self): + return self + + def __next__(self): + try: + return self.__next_cpp() + except Exception as e: + raise StopIteration + + + def next(self): + return self.__next__() + +%} +} + +%extend akantu::CSR +{ + akantu::CSRIterator row(akantu::UInt row){ + return akantu::CSRIterator(*$self,row); + } +} + +%include "aka_csr.hh" +namespace akantu { + %template (CSRUInt) CSR; + %template (CSRElement) CSR; + %template(CSRIteratorElement) CSRIterator; +} diff --git a/python/swig/mesh.i b/python/swig/mesh.i index 87acb6764..a6384cd75 100644 --- a/python/swig/mesh.i +++ b/python/swig/mesh.i @@ -1,116 +1,127 @@ %{ #include "mesh.hh" #include "node_group.hh" #include "solid_mechanics_model.hh" - +#include "dumpable_inline_impl.hh" + using akantu::QuadraturePoint; using akantu::Vector; using akantu::ElementTypeMapArray; using akantu::MatrixProxy; using akantu::Matrix; using akantu::UInt; using akantu::Real; using akantu::Array; using akantu::SolidMechanicsModel; + %} namespace akantu { %ignore NewNodesEvent; %ignore RemovedNodesEvent; %ignore NewElementsEvent; %ignore RemovedElementsEvent; %ignore MeshEventHandler; %ignore MeshEvent< UInt >; %ignore MeshEvent< Element >; %ignore Mesh::extractNodalCoordinatesFromPBCElement; %ignore Mesh::getGroupDumer; %ignore Mesh::getFacetLocalConnectivity; %ignore Mesh::getAllFacetTypes; } print_self(Mesh) %extend akantu::Mesh { void resizeMesh(UInt nb_nodes, UInt nb_element, const ElementType & type) { Array & nodes = const_cast &>($self->getNodes()); nodes.resize(nb_nodes); $self->addConnectivityType(type); Array & connectivity = const_cast &>($self->getConnectivity(type)); connectivity.resize(nb_element); } } %extend akantu::GroupManager { void createGroupsFromStringMeshData(const std::string & dataset_name) { $self->createGroupsFromMeshData(dataset_name); } void createGroupsFromUIntMeshData(const std::string & dataset_name) { $self->createGroupsFromMeshData(dataset_name); } } %extend akantu::NodeGroup { akantu::Array & getGroupedNodes(akantu::Array & surface_array, Mesh & mesh) { akantu::Array group_node = $self->getNodes(); akantu::Array & full_array = mesh.getNodes(); surface_array.resize(group_node.getSize()); for (UInt i = 0; i < group_node.getSize(); ++i) { for (UInt cmp = 0; cmp < full_array.getNbComponent(); ++cmp) { surface_array(i,cmp) = full_array(group_node(i),cmp); } } akantu::Array & res(surface_array); return res; } akantu::Array & getGroupedArray(akantu::Array & surface_array, akantu::SolidMechanicsModel & model, int type) { akantu::Array * full_array; switch (type) { case 0 : full_array = new akantu::Array(model.getDisplacement()); break; case 1 : full_array = new akantu::Array(model.getVelocity()); break; case 2 : full_array = new akantu::Array(model.getForce()); break; } akantu::Array group_node = $self->getNodes(); surface_array.resize(group_node.getSize()); for (UInt i = 0; i < group_node.getSize(); ++i) { for (UInt cmp = 0; cmp < full_array->getNbComponent(); ++cmp) { surface_array(i,cmp) = (*full_array)(group_node(i),cmp); } } akantu::Array & res(surface_array); return res; } } %include "group_manager.hh" %include "element_group.hh" %include "node_group.hh" - +%include "dumper_iohelper.hh" +%include "dumpable_iohelper.hh" %include "mesh.hh" +namespace akantu{ +%extend Dumpable { + void addDumpFieldExternalReal(const std::string & field_id, + const Array & field){ + $self->addDumpFieldExternal(field_id,field); + } + } + } diff --git a/python/swig/mesh_utils.i b/python/swig/mesh_utils.i index ae01d69b1..a20d0590b 100644 --- a/python/swig/mesh_utils.i +++ b/python/swig/mesh_utils.i @@ -1,8 +1,9 @@ namespace akantu { %ignore MeshPartition::getPartitions; %ignore MeshPartition::getPartition; %ignore MeshPartition::getGhostPartitionCSR; } %include "mesh_partition.hh" +%include "mesh_utils.hh" diff --git a/src/mesh_utils/mesh_utils.hh b/src/mesh_utils/mesh_utils.hh index e4a43cd08..ab73adabf 100644 --- a/src/mesh_utils/mesh_utils.hh +++ b/src/mesh_utils/mesh_utils.hh @@ -1,280 +1,270 @@ /** * @file mesh_utils.hh * * @author Guillaume Anciaux * @author Leonardo Snozzi * @author Marco Vocialta * @author Dana Christen * @author David Simon Kammer * @author Nicolas Richart * * @date creation: Fri Aug 20 2010 * @date last modification: Mon Jun 23 2014 * * @brief All mesh utils necessary for various tasks * * @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 "mesh.hh" #include "aka_csr.hh" #include "distributed_synchronizer.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MESH_UTILS_HH__ #define __AKANTU_MESH_UTILS_HH__ /* -------------------------------------------------------------------------- */ __BEGIN_AKANTU__ class MeshUtils { - /* ------------------------------------------------------------------------ */ - /* Constructors/Destructors */ - /* ------------------------------------------------------------------------ */ -public: - - MeshUtils(); - virtual ~MeshUtils(); /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// build a CSR that contains for each node the linearized number of /// the connected elements of a given spatial dimension static void buildNode2Elements(const Mesh & mesh, CSR & node_to_elem, UInt spatial_dimension = _all_dimensions); /// build a CSR that contains for each node the list of connected /// elements ofr a given spatial dimension static void buildNode2Elements(const Mesh & mesh, CSR & node_to_elem, UInt spatial_dimension = _all_dimensions); /// build a CSR that contains for each node the number of /// the connected elements of a given ElementType static void buildNode2ElementsElementTypeMap(const Mesh & mesh, CSR & node_to_elem, const ElementType & type, const GhostType & ghost_type = _not_ghost); /// build the facets elements on the boundaries of a mesh static void buildFacets(Mesh & mesh); /// build all the facets elements: boundary and internals and store them in /// the mesh_facets for element of dimension from_dimension to to_dimension static void buildAllFacets(const Mesh & mesh, Mesh & mesh_facets, UInt from_dimension, UInt to_dimension, DistributedSynchronizer * synchronizer = NULL); /// build all the facets elements: boundary and internals and store them in /// the mesh_facets static void buildAllFacets(const Mesh & mesh, Mesh & mesh_facets, UInt to_dimension = 0, DistributedSynchronizer * synchronizer = NULL); /// build facets for a given spatial dimension static void buildFacetsDimension(const Mesh & mesh, Mesh & mesh_facets, bool boundary_only, UInt dimension, const ElementTypeMapArray * prank_to_element = NULL); /// take the local_connectivity array as the array of local and ghost /// connectivity, renumber the nodes and set the connectivity of the mesh static void renumberMeshNodes(Mesh & mesh, UInt * local_connectivities, UInt nb_local_element, UInt nb_ghost_element, ElementType type, Array & old_nodes); /// compute pbc pair for on given a direction static void computePBCMap(const Mesh & mymesh, const UInt dir, std::map & pbc_pair); /// compute pbc pair for a surface pair static void computePBCMap(const Mesh & mymesh, const std::pair & surface_pair, std::map & pbc_pair); - /// create a multimap of nodes per surfaces - static void buildNodesPerSurface(const Mesh & mesh, CSR & nodes_per_surface); - /// remove not connected nodes /!\ this functions renumbers the nodes. static void purifyMesh(Mesh & mesh); #if defined(AKANTU_COHESIVE_ELEMENT) /// function to insert cohesive elements on the selected facets /// @return number of facets that have been doubled static UInt insertCohesiveElements(Mesh & mesh, Mesh & mesh_facets, const ElementTypeMapArray & facet_insertion, Array & doubled_nodes, Array & new_elements, bool only_double_facets); #endif /// fill the subelement to element and the elements to subelements data static void fillElementToSubElementsData(Mesh & mesh); /// flip facets based on global connectivity static void flipFacets(Mesh & mesh_facets, const ElementTypeMapArray & global_connectivity, GhostType gt_facet); /// provide list of elements around a node and check if a given /// facet is reached template static bool findElementsAroundSubfacet(const Mesh & mesh, const Mesh & mesh_facets, const Element & starting_element, const Element & end_facet, const Vector & subfacet_connectivity, std::vector & elem_list, std::vector & facet_list, std::vector * subfacet_list = NULL); /// function to check if a node belongs to a given element static inline bool hasElement(const Array & connectivity, const Element & el, const Vector & nodes); /// reset facet_to_double arrays in the Mesh static void resetFacetToDouble(Mesh & mesh_facets); private: /// match pairs that are on the associated pbc's static void matchPBCPairs(const Mesh & mymesh, const UInt dir, Array & selected_left, Array & selected_right, std::map & pbc_pair); /// function used by all the renumbering functions static void renumberNodesInConnectivity(UInt * list_nodes, UInt nb_nodes, std::map & renumbering_map); /// update facet_to_subfacet static void updateFacetToSubfacet(Mesh & mesh_facets, ElementType type_subfacet, GhostType gt_subfacet, bool facet_mode); /// update subfacet_to_facet static void updateSubfacetToFacet(Mesh & mesh_facets, ElementType type_subfacet, GhostType gt_subfacet, bool facet_mode); /// function to double a given facet and update the list of doubled /// nodes static void doubleFacet(Mesh & mesh, Mesh & mesh_facets, UInt facet_dimension, Array & doubled_nodes, bool facet_mode); /// function to double a subfacet given start and end index for /// local facet_to_subfacet vector, and update the list of doubled /// nodes template static void doubleSubfacet(Mesh & mesh, Mesh & mesh_facets, Array & doubled_nodes); /// double a node static void doubleNodes(Mesh & mesh, const std::vector & old_nodes, Array & doubled_nodes); /// fill facet_to_double array in the mesh /// returns the number of facets to be doubled static UInt updateFacetToDouble(Mesh & mesh_facets, const ElementTypeMapArray & facet_insertion); /// find subfacets to be doubled template static void findSubfacetToDouble(Mesh & mesh, Mesh & mesh_facets); /// double facets (points) in 1D static void doublePointFacet(Mesh & mesh, Mesh & mesh_facets, Array & doubled_nodes); #if defined(AKANTU_COHESIVE_ELEMENT) /// update cohesive element data static void updateCohesiveData(Mesh & mesh, Mesh & mesh_facets, Array & new_elements); #endif /// update elemental connectivity after doubling a node inline static void updateElementalConnectivity(Mesh & mesh, UInt old_node, UInt new_node, const std::vector & element_list, const std::vector * facet_list = NULL); /// double middle nodes if facets are _segment_3 template static void updateQuadraticSegments(Mesh & mesh, Mesh & mesh_facets, ElementType type_facet, GhostType gt_facet, Array & doubled_nodes); /// remove elements on a vector inline static bool removeElementsInVector(const std::vector & elem_to_remove, std::vector & elem_list); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ #include "mesh_utils_inline_impl.cc" __END_AKANTU__ #endif /* __AKANTU_MESH_UTILS_HH__ */