Commit 1d695006 authored by Pierre Kraemer's avatar Pierre Kraemer

remove old OpenNL + update algos for new version

parent d8eb0172
......@@ -73,6 +73,7 @@ SET (EXT_INCLUDES
# define libs for external libs
SET (EXT_LIBS
PythonQt
nl
${OPENGL_LIBRARY}
${GLEW_LIBRARIES}
${ZLIB_LIBRARIES}
......
......@@ -8,14 +8,15 @@
#include "Container/fakeAttribute.h"
#include "OpenNL/linear_solver.h"
#include "NL/nl.h"
#include "Algo/LinearSolving/basic.h"
#include "Eigen/Dense"
using namespace CGoGN;
using namespace SCHNApps;
// namespace CGoGN { namespace Utils { class Drawer; } }
namespace CGoGN { namespace Utils { class Drawer; } }
enum SelectionMode
......@@ -51,7 +52,8 @@ struct PerMapParameterSet
VertexAttribute<unsigned int> vIndex;
unsigned int nb_vertices;
LinearSolver<PFP2::REAL>* solver;
// LinearSolver<PFP2::REAL>* solver;
NLContext nlContext;
};
struct ParameterSet
......@@ -143,7 +145,7 @@ private:
SurfaceDeformationDockTab* m_dockTab;
QHash<View*, ParameterSet*> h_viewParams;
// Utils::Drawer* m_drawer;
Utils::Drawer* m_drawer;
bool b_refreshingUI;
......
importPlugin = schnapps.loadPlugin("ImportSurface");
renderPlugin = schnapps.loadPlugin("Render");
renderVectorPlugin = schnapps.loadPlugin("RenderVector");
differentialPropertiesPlugin = schnapps.loadPlugin("DifferentialProperties");
subdivisionPlugin = schnapps.loadPlugin("SubdivideSurface");
#renderVectorPlugin = schnapps.loadPlugin("RenderVector");
#differentialPropertiesPlugin = schnapps.loadPlugin("DifferentialProperties");
#subdivisionPlugin = schnapps.loadPlugin("SubdivideSurface");
surfaceDeformationPlugin = schnapps.loadPlugin("SurfaceDeformation");
#obj = importPlugin.importFromFile("/home/kraemer/Media/Data/surface/lowRes/iphi_good_9k.off");
obj = importPlugin.importFromFile("/home/kraemer/Media/Data/surface/lowRes/iphi_good_9k.off");
#v = schnapps.getView("view_0");
v = schnapps.getView("view_0");
#schnapps.linkViewAndPlugin(v.getName(), renderPlugin.getName());
schnapps.linkViewAndPlugin(v.getName(), renderPlugin.getName());
#schnapps.linkViewAndPlugin(v.getName(), renderVectorPlugin.getName());
#schnapps.linkViewAndPlugin(v.getName(), surfaceDeformationPlugin.getName());
schnapps.linkViewAndPlugin(v.getName(), surfaceDeformationPlugin.getName());
#schnapps.linkViewAndMap(v.getName(), obj.getName());
schnapps.linkViewAndMap(v.getName(), obj.getName());
#differentialPropertiesPlugin.computeNormal(obj.getName());
#differentialPropertiesPlugin.computeCurvature(obj.getName());
......@@ -15,7 +15,7 @@ ELSE (${CMAKE_CURRENT_BINARY_DIR} MATCHES "(.*)Debug")
ENDIF (${CMAKE_CURRENT_BINARY_DIR} MATCHES "(.*)Debug")
IF(WIN32)
SET(LIBRARY_OUTPUT_PATH ${CGoGN_ROOT_DIR}/lib)#release added by visual
SET(LIBRARY_OUTPUT_PATH ${CGoGN_ROOT_DIR}/lib) #release added by visual
INCLUDE_DIRECTORIES(${CGoGN_ROOT_DIR}/windows_dependencies/include/)
ELSE(WIN32)
SET(LIBRARY_OUTPUT_PATH ${CGoGN_ROOT_DIR}/lib/${CMAKE_BUILD_TYPE})
......@@ -40,6 +40,9 @@ add_subdirectory(Tools Tools/build)
add_subdirectory(PythonQt PythonQt/build)
INSTALL (DIRECTORY PythonQt/src/ DESTINATION ${CGoGN_ROOT_DIR}/ThirdParty/include/PythonQt FILES_MATCHING PATTERN "*.h")
add_subdirectory(OpenNL OpenNL/build)
INSTALL (DIRECTORY OpenNL/src/NL/ DESTINATION ${CGoGN_ROOT_DIR}/ThirdParty/include/NL FILES_MATCHING PATTERN "*.h")
IF (WITH_ZINRI)
add_subdirectory(Zinri Zinri/build)
INSTALL (DIRECTORY Zinri/ DESTINATION ${CGoGN_ROOT_DIR}/ThirdParty/include/Zinri FILES_MATCHING PATTERN "*.h")
......
This diff is collapsed.
--------------------- Open Numerical Library <T> -------------------------
General information
===================
This is OpenNL<T>, a library to easily construct and solve sparse linear systems.
* OpenNL<T> is supplied with a set of built-in iterative solvers
(Conjugate gradient and BICGSTAB)
* OpenNL can also use other solvers (by writing a SolverTraits class)
* ../lscm_with_generic_api.cpp implements the LSCM parameterization method with OpenNL<T>
Sorry, there is no more doc than that ...
/*
* OpenNL<T>: Generic Numerical Library
* Copyright (C) 2004 Bruno Levy
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* In addition, as a special exception, the INRIA gives permission to link the
* code of this program with the CGAL library, and distribute linked combinations
* including the two. You must obey the GNU General Public License in all respects
* for all of the code used other than CGAL.
*
* If you modify this software, you should include a notice giving the
* name of the person performing the modification, the date of modification,
* and the reason for such modification.
*
* Contact: Bruno Levy
*
* levy@loria.fr
*
* ISA-ALICE Project
* LORIA, INRIA Lorraine,
* Campus Scientifique, BP 239
* 54506 VANDOEUVRE LES NANCY CEDEX
* FRANCE
*
* Note that the GNU General Public License does not permit incorporating
* the Software into proprietary programs.
*/
#ifndef __BICGSTAB__
#define __BICGSTAB__
#include <cmath>
#include <cassert>
#include "blas.h"
/**
* The BICGSTAB algorithm without preconditioner:
* Ashby, Manteuffel, Saylor
* A taxononmy for conjugate gradient methods
* SIAM J Numer Anal 27, 1542-1568 (1990)
*
* This implementation is inspired by the lsolver library,
* by Christian Badura, available from:
* http://www.mathematik.uni-freiburg.de
* /IAM/Research/projectskr/lin_solver/
*
* @param A generic matrix, a function
* mult(const MATRIX& M, const double* x, double* y)
* needs to be defined.
* @param b right hand side of the system.
* @param x initial value.
* @param eps threshold for the residual.
* @param max_iter maximum number of iterations.
*/
template < class MATRIX, class VECTOR>
class Solver_BICGSTAB {
public:
typedef MATRIX Matrix ;
typedef VECTOR Vector ;
typedef typename Vector::CoeffType CoeffType ;
Solver_BICGSTAB() {
epsilon_ = 1e-5 ;
max_iter_ = 0 ;
}
void set_epsilon(CoeffType eps) { epsilon_ = eps ; }
void set_max_iter(unsigned int max_iter) { max_iter_ = max_iter ; }
void solve(const MATRIX &A, const VECTOR& b, VECTOR& x) {
assert(A.n() == A.m()) ;
assert(A.has_symmetric_storage()) ;
assert(A.n() == b.dimension()) ;
assert(A.n() == x.dimension()) ;
unsigned int n = A.n() ;
unsigned int max_iter = max_iter_ ;
if(max_iter == 0) {
max_iter = 5 * n ;
}
Vector rT(n) ;
Vector d(n) ;
Vector h(n) ;
Vector u(n) ;
Vector Ad(n) ;
Vector t(n) ;
Vector& s = h ;
CoeffType rTh, rTAd, rTr, alpha, beta, omega, st, tt ;
unsigned int its = 0 ;
CoeffType err = epsilon_ * epsilon_ * BLAS<Vector>::dot(b,b) ;
Vector r(n) ;
mult(A,x,r) ;
BLAS<Vector>::axpy(-1,b,r) ;
BLAS<Vector>::copy(r,d) ;
BLAS<Vector>::copy(d,h) ;
BLAS<Vector>::copy(h,rT) ;
assert( BLAS<Vector>::dot(rT,rT)>1e-40 ) ;
rTh=BLAS<Vector>::dot(rT,h) ;
rTr=BLAS<Vector>::dot(r,r) ;
while ( rTr > err && its < max_iter) {
mult(A,d,Ad) ;
rTAd = BLAS<Vector>::dot(rT,Ad) ;
assert( fabs(rTAd)>1e-40 ) ;
alpha = rTh/rTAd ;
BLAS<Vector>::axpy(-alpha,Ad,r) ;
BLAS<Vector>::copy(h,s) ;
BLAS<Vector>::axpy(-alpha,Ad,s) ;
mult(A,s,t) ;
BLAS<Vector>::axpy(1,t,u) ;
BLAS<Vector>::scal(alpha,u) ;
st = BLAS<Vector>::dot(s,t) ;
tt = BLAS<Vector>::dot(t,t) ;
if ( fabs(st) < 1e-40 || fabs(tt) < 1e-40 )
omega = 0 ;
else
omega = st/tt ;
BLAS<Vector>::axpy(-omega,t,r) ;
BLAS<Vector>::axpy(-alpha,d,x) ;
BLAS<Vector>::axpy(-omega,s,x) ;
BLAS<Vector>::copy(s,h) ;
BLAS<Vector>::axpy(-omega,t,h) ;
beta = (alpha/omega) / rTh ;
rTh = BLAS<Vector>::dot(rT,h) ;
beta *= rTh ;
BLAS<Vector>::scal(beta,d) ;
BLAS<Vector>::axpy(1,h,d) ;
BLAS<Vector>::axpy(-beta*omega,Ad,d) ;
rTr = BLAS<Vector>::dot(r,r) ;
its++ ;
}
}
private:
CoeffType epsilon_ ;
unsigned int max_iter_ ;
} ;
#endif
/*
* OpenNL<T>: Generic Numerical Library
* Copyright (C) 2004 Bruno Levy
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* In addition, as a special exception, the INRIA gives permission to link the
* code of this program with the CGAL library, and distribute linked combinations
* including the two. You must obey the GNU General Public License in all respects
* for all of the code used other than CGAL.
*
* If you modify this software, you should include a notice giving the
* name of the person performing the modification, the date of modification,
* and the reason for such modification.
*
* Contact: Bruno Levy
*
* levy@loria.fr
*
* ISA-ALICE Project
* LORIA, INRIA Lorraine,
* Campus Scientifique, BP 239
* 54506 VANDOEUVRE LES NANCY CEDEX
* FRANCE
*
* Note that the GNU General Public License does not permit incorporating
* the Software into proprietary programs.
*/
#ifndef __BLAS__
#define __BLAS__
#include <cassert>
/*
* Basic Linear Algebra Subroutines
*
* VectorType should have the following members :
* CoeffType -> type of the coefficients used in the vector
* operator[](unsigned int i)
* dimension()
*
*/
template <class VectorType>
class BLAS {
public:
typedef typename VectorType::CoeffType CoeffType ;
/** y <- y + a*x */
static void axpy(CoeffType a, const VectorType& x, VectorType& y) {
assert(x.dimension() == y.dimension()) ;
for(unsigned int i=0; i<x.dimension(); i++) {
y[i] += a * x[i] ;
}
}
/** x <- a*x */
static void scal(CoeffType a, VectorType& x) {
for(unsigned int i=0; i<x.dimension(); i++) {
x[i] *= a ;
}
}
/** y <- x */
static void copy(const VectorType& x, VectorType& y) {
assert(x.dimension() == y.dimension()) ;
for(unsigned int i=0; i<x.dimension(); i++) {
y[i] = x[i] ;
}
}
/** returns x^t * y */
static CoeffType dot(const VectorType& x, const VectorType& y) {
CoeffType result = 0 ;
assert(x.dimension() == y.dimension()) ;
for(unsigned int i=0; i<x.dimension(); i++) {
result += y[i] * x[i] ;
}
return result ;
}
} ;
#endif
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg *
* *
* This library 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 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library 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 this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: http://cgogn.unistra.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#ifndef __GPU_CONJUGATE_GRADIENT__
#define __GPU_CONJUGATE_GRADIENT__
#include "CNC/cnc_gpu_solver.h"
template< class MATRIX, class VECTOR >
class Solver_CG_GPU
{
public:
typedef MATRIX Matrix ;
typedef VECTOR Vector ;
typedef typename Vector::CoeffType CoeffType ;
Solver_CG_GPU() {
epsilon_ = 1e-5 ;
max_iter_ = 2000 ;
}
void set_epsilon(CoeffType eps) { epsilon_ = eps ; }
void set_max_iter(unsigned int max_iter) { max_iter_ = max_iter ; }
void solve(const MATRIX &A, const VECTOR& b, VECTOR& x) {
CNCGPUSolver::solve_cg(A, b, x, max_iter_, epsilon_, 1) ;
}
private:
CoeffType epsilon_ ;
unsigned int max_iter_ ;
} ;
#endif
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg *
* *
* This library 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 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library 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 this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: http://cgogn.unistra.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
/*
* This interface to CHOLMOD is largely inspired from the one found in
* Graphite developped by Bruno Levy, ALICE Project, LORIA, INRIA Lorraine
*/
#ifndef __CHOLESKY_SOLVER__
#define __CHOLESKY_SOLVER__
#include <cassert>
#include <cholmod.h>
template <typename CoeffType>
class Solver_CHOLESKY
{
public:
Solver_CHOLESKY() {
N = 0 ;
factorized_ = false ;
L = NULL ;
// Initialize CHOLMOD library
cholmod_start(&c) ;
}
~Solver_CHOLESKY() {
cholmod_free_factor(&L, &c) ;
cholmod_finish(&c) ;
}
bool factorized() { return factorized_ ; }
void factorize(const Eigen::SparseMatrix<CoeffType>& A_in) {
assert(A_in.rows() == A_in.cols()) ;
// assert(A_in.has_symmetric_storage()) ;
N = A_in.rows() ;
// Translate sparse matrix into cholmod format
int NNZ = A_in.nonZeros() ;
cholmod_sparse* A = cholmod_allocate_sparse(N, N, NNZ, false, true, -1, CHOLMOD_REAL, &c);
int* colptr = static_cast<int*>(A->p) ;
int* rowind = static_cast<int*>(A->i) ;
double* a = static_cast<double*>(A->x) ;
// Convert local Matrix into CHOLMOD Matrix
int count = 0 ;
for(int j = 0; j < N; j++) {
colptr[j] = count;
for(typename Eigen::SparseMatrix<CoeffType>::InnerIterator it(A_in, j); it; ++it)
{
a[count] = it.value();
rowind[count] = it.row();
++count;
}
}
colptr[N] = NNZ ;
// Factorize
L = cholmod_analyze(A, &c) ;
cholmod_factorize(A, L, &c) ;
factorized_ = true ;
// Cleanup
cholmod_free_sparse(&A, &c) ;
}
void solve(const Eigen::Matrix<CoeffType, Eigen::Dynamic, 1>& b_in, Eigen::Matrix<CoeffType, Eigen::Dynamic, 1>& x_out) {
assert(factorized_) ;
assert(L->n == b_in.rows()) ;
assert(L->n == x_out.rows()) ;
// Translate right-hand side into cholmod format
cholmod_dense* b = cholmod_allocate_dense(N, 1, N, CHOLMOD_REAL, &c) ;
double* cb = static_cast<double*>(b->x) ;
for(int i = 0; i < N; ++i)
cb[i] = b_in[i] ;
// Solve
cholmod_dense* x = cholmod_solve(CHOLMOD_A, L, b, &c) ;
// Get result
double* cx = static_cast<double*>(x->x) ;
for(int i = 0; i < N; ++i)
x_out[i] = cx[i] ;
// Cleanup
cholmod_free_dense(&b, &c) ;
cholmod_free_dense(&x, &c) ;
}
void reset() {
if(factorized_)
{
cholmod_free_factor(&L, &c) ;
factorized_ = false ;
L = NULL ;
}
}
private:
int N ;
bool factorized_ ;
cholmod_common c ;
cholmod_factor* L ;
} ;
#endif
/*
* OpenNL<T>: Generic Numerical Library
* Copyright (C) 2004 Bruno Levy
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* In addition, as a special exception, the INRIA gives permission to link the
* code of this program with the CGAL library, and distribute linked combinations
* including the two. You must obey the GNU General Public License in all respects
* for all of the code used other than CGAL.
*
* If you modify this software, you should include a notice giving the
* name of the person performing the modification, the date of modification,
* and the reason for such modification.
*
* Contact: Bruno Levy
*
* levy@loria.fr
*
* ISA-ALICE Project
* LORIA, INRIA Lorraine,
* Campus Scientifique, BP 239
* 54506 VANDOEUVRE LES NANCY CEDEX
* FRANCE
*
* Note that the GNU General Public License does not permit incorporating
* the Software into proprietary programs.
*/
#ifndef __CONJUGATE_GRADIENT__
#define __CONJUGATE_GRADIENT__
#include <cassert>
#include "blas.h"
/**
* The Conjugate Gradient algorithm without preconditioner:
* Ashby, Manteuffel, Saylor
* A taxononmy for conjugate gradient methods
* SIAM J Numer Anal 27, 1542-1568 (1990)
*
* This implementation is inspired by the lsolver library,
* by Christian Badura, available from:
* http://www.mathematik.uni-freiburg.de
* /IAM/Research/projectskr/lin_solver/
*
* @param A generic matrix, a function
* mult(const MATRIX& M, const double* x, double* y)
* needs to be defined.
* @param b right hand side of the system.
* @param x initial value.
* @param eps threshold for the residual.
* @param max_iter maximum number of iterations.
*/
template< class MATRIX, class VECTOR >
class Solver_CG
{
public:
typedef MATRIX Matrix ;
typedef VECTOR Vector ;
typedef typename Vector::CoeffType CoeffType ;
Solver_CG() {
epsilon_ = 1e-5 ;
max_iter_ = 0 ;
}
void set_epsilon(CoeffType eps) { epsilon_ = eps ; }
void set_max_iter(unsigned int max_iter) { max_iter_ = max_iter ; }
void solve(const MATRIX& A, const VECTOR& b, VECTOR& x) {
assert(A.n() == A.m()) ;
assert(A.has_symmetric_storage()) ;
assert(A.n() == b.dimension()) ;
assert(A.n() == x.dimension()) ;
unsigned int n = A.n() ;
unsigned int max_iter = max_iter_ ;
if(max_iter == 0) {
max_iter = 5 * n ;
}
Vector g(n) ;
Vector r(n) ;
Vector p(n) ;
unsigned int its = 0 ;
CoeffType t, tau, sig, rho, gam ;
CoeffType bnorm2 = BLAS<Vector>::dot(b,b) ;
CoeffType err = epsilon_ * epsilon_ * bnorm2 ;
mult(A,x,g) ;
BLAS<Vector>::axpy(-1,b,g) ;
BLAS<Vector>::scal(-1,g) ;
BLAS<Vector>::copy(g,r) ;
while ( BLAS<Vector>::dot(g,g) > err && its < max_iter) {
mult(A,r,p) ;
rho = BLAS<Vector>::dot(p,p) ;
sig = BLAS<Vector>::dot(r,p) ;
tau = BLAS<Vector>::dot(g,r) ;
t = tau / sig ;
BLAS<Vector>::axpy(t,r,x) ;
BLAS<Vector>::axpy(-t,p,g) ;
gam = (t*t*rho-tau) / tau ;
BLAS<Vector>::scal(gam,r) ;
BLAS<Vector>::axpy(1,g,r) ;
its++ ;
}
}
private:
CoeffType epsilon_ ;
unsigned int max_iter_ ;
} ;
#endif
/*
* OpenNL<T>: Generic Numerical Library
* Copyright (C) 2004 Bruno Levy
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* In addition, as a special exception, the INRIA gives permission to link the
* code of this program with the CGAL library, and distribute linked combinations
* including the two. You must obey the GNU General Public License in all respects
* for all of the code used other than CGAL.
*
* If you modify this software, you should include a notice giving the
* name of the person performing the modification, the date of modification,
* and the reason for such modification.
*
* Contact: Bruno Levy
*
* levy@loria.fr
*
* ISA-ALICE Project
* LORIA, INRIA Lorraine,
* Campus Scientifique, BP 239
* 54506 VANDOEUVRE LES NANCY CEDEX