diff --git a/python/surface.i b/python/surface.i index 4edce57..56af971 100644 --- a/python/surface.i +++ b/python/surface.i @@ -1,375 +1,372 @@ /** * * @author Guillaume Anciaux * * @section LICENSE * * Copyright (©) 2016 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Tamaas 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. * * Tamaas 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 Tamaas. If not, see . * */ /* -------------------------------------------------------------------------- */ %{ #include #include "map_2d.hh" #include "surface.hh" #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #include #include "surface_generator_filter_fft.hh" #include "smart_pointer.hh" #include "surface_statistics.hh" #include "bem_kato.hh" #include "bem_polonski.hh" #include "bem_penalty.hh" #include "bem_gigi.hh" #include "bem_gigipol.hh" #include "bem_uzawa.hh" #include "bem_fft_base.hh" #include "bem_grid.hh" #include "bem_grid_polonski.hh" #include "contact_area.hh" #include "contact_cluster_collection.hh" #include "functional.hh" #include "meta_functional.hh" #include "elastic_energy_functional.hh" #include "complimentary_term_functional.hh" #include "exponential_adhesion_functional.hh" #include "maugis_adhesion_functional.hh" #include "surface_timer.hh" #include "fftransform_fftw.hh" %} %include "cpointer.i" %include "typemaps.i" %include "numpy.i" %init %{ import_array(); %} /* -------------------------------------------------------------------------- */ /* Wrapping returned pointers /* -------------------------------------------------------------------------- */ //%include "typemaps.i" %include "std_string.i" %include "std_vector.i" %include "smart_pointer.hh" %template(VectorReal) std::vector; //%pointer_functions(int, intp); //%pointer_functions(long, longp); //%pointer_functions(unsigned int, uintp); //%pointer_functions(double, doublep); //%pointer_functions(float, floatp); //%pointer_functions(std::complex, comlpexp); %define %my_pointer_class(NAME,TYPE) %template(SmartPointer##NAME) SmartPointer< TYPE >; %typemap(out) TYPE & { #define TOREPLACE SWIGTYPE_p_SmartPointerT_##NAME##_t SmartPointer * ptr = new SmartPointer($1); $result = SWIG_NewPointerObj(SWIG_as_voidptr(ptr), TOREPLACE, 0 | 0 ); #undef TOREPLACE } %enddef %my_pointer_class(int,int) %my_pointer_class(double,double) %my_pointer_class(long,long) %my_pointer_class(vectorReal,std::vector) /* -------------------------------------------------------------------------- */ /* Wrapping Surface class */ /* -------------------------------------------------------------------------- */ %include "tamaas.hh" %ignore tamaas::Grid::iterator::operator++; %ignore *::operator=; %include "grid.hh" %include "grid_hermitian.hh" namespace tamaas { %template (Grid1dReal) Grid; %template (Grid2dReal) Grid; %template (Grid2dComplex) Grid; %template (Grid2dInt) Grid; %template (Grid2dUInt) Grid; %template (GridHermitian2dReal) GridHermitian; } %include "grid_hermitian.hh" %include "map_2d.hh" namespace tamaas { %template(Map2dComplex) Map2d; %template(Map2dInt) Map2d; %template(Map2dReal) Map2d; } %include "map_2d_square.hh" namespace tamaas { %template(Map2dSquareComplex) Map2dSquare; %template(Map2dSquareInt) Map2dSquare; %template(Map2dSquareReal) Map2dSquare; } %include "surface.hh" %include "surface_complex.hh" namespace tamaas { %template(SurfaceReal) Surface; %template(SurfaceInt) Surface; %template(SurfaceRealComplex) SurfaceComplex; } +%inline %{ + __BEGIN_TAMAAS__ + template + void sanityCheck(PyObject * input) { + if (PyArray_TYPE((PyArrayObject*)input) != required_type) + throw Exception("Sanity check: python object stores wrong type"); + } + __END_TAMAAS__ +%} + %inline %{ __BEGIN_TAMAAS__ template class GridForPython : public Grid { public: GridForPython(T * wrapped_memory, UInt n[d], Real L[d], UInt nb_components): Grid() { this->__init__(wrapped_memory, n, L); } void __init__(T * w, UInt n[d], UInt nb_components) { memcpy(this->n, n, d * sizeof(UInt)); memset(this->L, 1, d * sizeof(Real)); this->nb_components = nb_components; this->data.wrapMemory(w, this->computeSize()); } GridForPython(PyObject * input): Grid() { if (!PyArray_Check(input)) { PyObject* obj_type = PyObject_Type(input); std::string type = PyString_AsString(obj_type); throw Exception("GridForPython: incompatible input which is not a numpy: " + type); } UInt _n = PyArray_NDIM((PyArrayObject*)input); // numpy number of dimensions npy_intp * ndims = PyArray_DIMS((PyArrayObject*)input); // numpy dimensions UInt grid_dims[d] = {0}; // tamaas dims if (_n >= d) { for (UInt i = 0 ; i < d ; ++i) grid_dims[i] = ndims[i]; } else { throw Exception("GridForPython: incompatible input size for numpy array: " + _n); } if (_n > d) this->nb_components = ndims[d+1]; else this->nb_components = 1; PyArrayIterObject *iter = (PyArrayIterObject *)PyArray_IterNew(input); if (iter == NULL) throw; this->__init__(( T *)(iter->dataptr), grid_dims, this->nb_components); Py_DECREF(iter); } virtual ~GridForPython() {} - - void sanityCheck(PyObject * input, int required_type) { - if (PyArray_TYPE((PyArrayObject*)input) != required_type) - throw Exception("GridForPython: python object stores wrong type"); - } }; __END_TAMAAS__ %} %inline %{ __BEGIN_TAMAAS__ template class SurfaceForPython : public Surface{ public: SurfaceForPython(T * wrapped_memory, UInt n, Real L) : Surface(0,L){ this->__init__(wrapped_memory,n,L); }; void __init__(T * wrapped_memory, UInt n, Real L){ this->n[0] = n; this->n[1] = n; this->data.wrapMemory(wrapped_memory,n*n); } SurfaceForPython(PyObject * input, Real L = 1.) : Surface(0,L){ if (!PyArray_Check(input)){ PyObject* obj_type = PyObject_Type(input); std::string type = PyString_AsString(obj_type); throw Exception("SurfaceForPython: incompatible input which is not a numpy: " + type); } UInt _n = PyArray_NDIM((PyArrayObject*)input); if (_n != 2) SURFACE_FATAL("SurfaceForPython: incompatible numpy dimension " << _n); npy_intp * ndims = PyArray_DIMS((PyArrayObject*)input); UInt sz = ndims[0]; UInt sz2 = ndims[1]; if (sz != sz2) SURFACE_FATAL("SurfaceForPython: incompatible numpy dimensions " << sz << " " << sz2); PyArrayIterObject *iter = (PyArrayIterObject *)PyArray_IterNew(input); if (iter == NULL) throw; this->__init__(( T *)(iter->dataptr),sz,L); Py_DECREF(iter); }; ~SurfaceForPython(){ }; void resize(UInt new_size){ if (this->size() != new_size) throw Exception("SurfaceForPython: cannot resize a temporary vector"); } - - void sanityCheck(PyObject * input, int required_type) { - if (PyArray_TYPE((PyArrayObject*)input) != required_type) - throw Exception("SurfaceForPython: python object stores wrong type"); - } - }; __END_TAMAAS__ %} %define %grid_typemaps(GRID_CLASS, DATA_TYPE, DATA_TYPECODE, DIM) %typemap(out, fragment="NumPy_Fragments") (GRID_CLASS &) { using namespace tamaas; UInt additional_dim = ($1->getNbComponents() == 1)? 0:1; UInt dim = DIM+additional_dim; npy_intp dims[dim]; for (UInt i = 0 ; i < DIM ; i++) dims[i] = (npy_intp)$1->sizes()[i]; if (additional_dim) dims[dim-1] = $1->getNbComponents(); DATA_TYPE * data = const_cast($1->getInternalData()); PyObject* obj = PyArray_SimpleNewFromData(dim, dims, DATA_TYPECODE, &data[0]); PyArrayObject* array = (PyArrayObject*) obj; if (!array) SWIG_fail; $result = SWIG_Python_AppendOutput($result, obj); } %typemap(in) tamaas::Grid & { using namespace tamaas; if (!PyArray_Check($input)) { PyObject* objectsRepresentation = PyObject_Repr(PyObject_Type($input)); const char* s = PyString_AsString(objectsRepresentation); std::string __type = s; if ("" == __type) { SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,0); } else if ("" == __type) { SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,0); } else throw tamaas::Exception("typemap: incompatible input which is not a proper type: " + __type + " (DATATYPE = " + std::string("DATA_TYPE") + ")"); } else { $1 = new GridForPython< DATA_TYPE, DIM >($input); - GridForPython< DATA_TYPE, DIM > * g = dynamic_cast * >($1); - g->sanityCheck($input, DATA_TYPECODE); + sanityCheck< DATA_TYPECODE >($input); } } %inline %{ namespace tamaas { GRID_CLASS & convertGrid(GRID_CLASS & s){ return s; } } %} %enddef %define %surface_typemaps(SURFACE_CLASS, DATA_TYPE, DATA_TYPECODE) %typemap(out, fragment="NumPy_Fragments") (SURFACE_CLASS &) { using namespace tamaas; UInt nz = $1->size(); npy_intp dims[2] = {nz,nz}; DATA_TYPE * data = const_cast($1->getInternalData()); PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, &data[0]); PyArrayObject* array = (PyArrayObject*) obj; if (!array) SWIG_fail; $result = SWIG_Python_AppendOutput($result, obj); } %typemap(in) tamaas::Surface< DATA_TYPE > & { using namespace tamaas; if (!PyArray_Check($input)){ PyObject* objectsRepresentation = PyObject_Repr(PyObject_Type($input)); const char* s = PyString_AsString(objectsRepresentation); std::string __type = s; if ("" == __type) { SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,0); } else if ("" == __type) { SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,0); } else if ("" == __type) { SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,0); } else throw tamaas::Exception("typemap: incompatible input which is not a proper type: " + __type + " (DATATYPE = " + std::string("DATA_TYPE") + ")"); } else{ $1 = new SurfaceForPython< DATA_TYPE >($input); - SurfaceForPython< DATA_TYPE > * g = dynamic_cast *>($1); - g->sanityCheck($input, DATA_TYPECODE); + sanityCheck< DATA_TYPECODE >($input); } } %inline %{ namespace tamaas { SURFACE_CLASS & convertSurface(SURFACE_CLASS & s){ return s; } } %} %enddef %surface_typemaps(tamaas::Surface, Real, NPY_DOUBLE) %surface_typemaps(tamaas::SurfaceComplex, std::complex, NPY_COMPLEX128 ) %surface_typemaps(tamaas::Surface, unsigned long, NPY_UINT ) %surface_typemaps(tamaas::Surface, UInt, NPY_UINT ) %surface_typemaps(tamaas::Surface, int, NPY_INT ) %grid_typemaps(tamaas::Grid1dReal, Real, NPY_DOUBLE, 1) %grid_typemaps(tamaas::Grid2dReal, Real, NPY_DOUBLE, 2) %grid_typemaps(tamaas::Grid2dComplex, tamaas::complex, NPY_COMPLEX128, 2) %grid_typemaps(tamaas::Grid2dUInt, UInt, NPY_UINT, 2) %grid_typemaps(tamaas::SurfaceComplex, tamaas::complex, NPY_COMPLEX128, 2) namespace tamaas { %template(SurfaceForPythonReal) SurfaceForPython< Real >; } %include "surface_timer.hh"