diff --git a/Solver/filters.cpp b/Solver/filters.cpp
index d48467dc84152d5b427f52ae82e3645bf22b8a7e..9869181b16cf3e12a6f9a7c63d636035a0b7cbfe 100644
--- a/Solver/filters.cpp
+++ b/Solver/filters.cpp
@@ -9,8 +9,259 @@
 //
 
 #include "filters.h"
+#include "MTriangle.h"
+#include "MQuadrangle.h"
+#include "MLine.h"
+#include "MTetrahedron.h"
+#include "MHexahedron.h"
+#include "MElementCut.h"
+#include "MElement.h"
 
 void FilterLevelSetForLagMultSpace::SortNodes (void)
 {
-	;
-}
\ No newline at end of file
+		
+		std::set< EdgeType > Se; // edges
+		std::set< NodeType > Sn; // level set nodes kept
+		std::map < NodeType, int > NodesScore;
+		std::map < NodeType , EdgeType > NodeToEdgeMap;
+		std::set< NodeType >::iterator itn;
+		
+		// initialization
+		fillNodeToEdgeMap (NodeToEdgeMap,Se,Sn);
+		
+		//-- decimation algorithm --
+		
+		
+		while (!Sn.empty())
+		{
+		// compute score of Sn
+		ComputeScore(NodeToEdgeMap,Se,Sn,NodesScore);
+		// take the lowest score
+		NodeType v = getNodeWithLowestScore(NodesScore);
+		// if NOT marked as looser then it s a winner
+		if (_looser_nodes.find(v) != _looser_nodes.end()) _winner_nodes.insert(v);
+		// kill all connected edges and nodes (then mark them as loosers)
+		killConnectedEdges (NodeToEdgeMap,Se,Sn,v);
+		}
+		
+		
+}
+
+void FilterLevelSetForLagMultSpace::fillNodeToEdgeMap(std::map < NodeType , EdgeType > & NodeToEdgeMap, std::set< EdgeType > & Se , std::set< NodeType > & Sn)
+{
+	std::set<MElement*>::const_iterator it = _LevelSetElements->begin();
+	for (; it != _LevelSetElements->end(); it++)
+		{
+			MElement *e = *it;
+			for (int i = 0 ; i < e->getNumVertices() ; i ++)  // warning getnumvertices polygon : vertices + inner ?
+			{
+				NodeType v = e->getVertex(i);
+				EdgeType edge = findEdge(v,e);
+				Sn.insert(v);
+				Se.insert(edge);
+				NodeToEdgeMap[v] = edge; 
+			}
+		}
+}
+
+std::pair <MVertex * , MVertex * > FilterLevelSetForLagMultSpace::findEdge(NodeType v, MElement * e)
+{
+	MElement *ep;
+	if (e->getParent()) ep = e->getParent();
+	switch (ep->getType())
+	{
+		case TYPE_TRI :
+		{
+			EdgeType edge;
+			for (int i = 0 ; i < 3 ; i ++)  // for all edges
+			{
+				int n1,n2;
+				n1 = i;
+				n2 = (i+1)%3;
+				// if it s an element vertex
+				if (v->getNum() == ep->getVertex(n1)->getNum())
+				{ 
+					edge = EdgeType (ep->getVertex(n1),ep->getVertex(n1));
+					return edge;
+				}
+				if (v->getNum() == ep->getVertex(n2)->getNum())
+				{
+					edge = EdgeType (ep->getVertex(n2),ep->getVertex(n2));
+					return edge;
+				}
+				// else if it s not an element vertex
+				edge = EdgeType(ep->getVertex(n1),ep->getVertex(n2));  
+			  if (NodeBelongToEdge(v,edge)) return edge;
+			}
+		}
+		case TYPE_QUA :
+		{
+			EdgeType edge;
+			for (int i = 0 ; i < 4 ; i ++)  // for all edges
+			{
+				int n1,n2;
+				n1 = i;
+				n2 = (i+1)%4;
+				// if it s an element vertex
+				if (v->getNum() == ep->getVertex(n1)->getNum())
+				{ 
+					edge = EdgeType (ep->getVertex(n1),ep->getVertex(n1));
+					return edge;
+				}
+				if (v->getNum() == ep->getVertex(n2)->getNum())
+				{
+					edge = EdgeType (ep->getVertex(n2),ep->getVertex(n2));
+					return edge;
+				}
+				// else if it s not an element vertex
+				edge = EdgeType(ep->getVertex(n1),ep->getVertex(n2));  
+			  if (NodeBelongToEdge(v,edge)) return edge;
+			}
+		}
+		case TYPE_TET :
+		{
+			int tab[6][2] = {{0, 1}, {0, 3}, {0, 2}, {1, 2}, {2, 3}, {3, 1}};  // edges
+			EdgeType edge;
+			for (int i = 0 ; i < 6 ; i ++)  // for all edges
+			{
+				int n1,n2;
+				n1 = tab[i][0];
+				n2 = tab[i][1];
+				// if it s an element vertex
+				if (v->getNum() == ep->getVertex(n1)->getNum())
+				{ 
+					edge = EdgeType (ep->getVertex(n1),ep->getVertex(n1));
+					return edge;
+				}
+				if (v->getNum() == ep->getVertex(n2)->getNum())
+				{
+					edge = EdgeType (ep->getVertex(n2),ep->getVertex(n2));
+					return edge;
+				}
+				// else if it s not an element vertex
+				edge = EdgeType(ep->getVertex(n1),ep->getVertex(n2));  
+			  if (NodeBelongToEdge(v,edge)) return edge;
+			}
+		}
+		case TYPE_HEX :
+		{
+			int tab[12][2] = {{0, 1}, {0, 4}, {0, 3}, {1, 2}, {1, 5},
+			                  {2, 3},{2,6},{3, 7}, {4, 7}, {4, 5},{5, 6},{6, 7}};// edges
+			EdgeType edge;
+			for (int i = 0 ; i < 12 ; i ++)  // for all edges
+			{
+				int n1,n2;
+				n1 = tab[i][0];
+				n2 = tab[i][1];
+				// if it s an element vertex
+				if (v->getNum() == ep->getVertex(n1)->getNum())
+				{ 
+					edge = EdgeType (ep->getVertex(n1),ep->getVertex(n1));
+					return edge;
+				}
+				if (v->getNum() == ep->getVertex(n2)->getNum())
+				{
+					edge = EdgeType (ep->getVertex(n2),ep->getVertex(n2));
+					return edge;
+				}
+				// else if it s not an element vertex
+				edge = EdgeType(ep->getVertex(n1),ep->getVertex(n2));  
+			  if (NodeBelongToEdge(v,edge)) return edge;
+			}
+		}
+		default : std::cout << "findEdge warning..." << std::endl;
+	}
+}
+
+
+bool FilterLevelSetForLagMultSpace::NodeBelongToEdge(NodeType v, EdgeType edge)
+{
+	
+	double eps = 1e-10;
+	
+	double distn, edgelength;
+	
+	edgelength = edge.first->distance(edge.second);
+	distn = v->distance(edge.first) + v->distance(edge.second);
+	
+	if (std::abs(edgelength - distn) < eps) return true;
+	else return false;
+	
+}
+
+
+void FilterLevelSetForLagMultSpace::ComputeScore(
+std::map < NodeType , EdgeType > & NodeToEdgeMap, std::set< EdgeType > & Se, std::set< NodeType > & Sn, std::map < NodeType , int > & NodesScore)
+{
+	NodesScore.clear();
+	std::set < NodeType >::iterator it = Sn.begin();
+  for (;it!=Sn.end();it++)
+	{
+		int score;
+		EdgeType edge;
+		edge = NodeToEdgeMap[(*it)];
+		if (edge.first->getNum() == edge.second->getNum()) score = 0;  // regular mesh nodes score
+		else score = ComputeIncidentEdges(Se,edge.first) + ComputeIncidentEdges(Se,edge.second);
+		NodesScore[(*it)] = score;
+	}
+}
+
+
+int FilterLevelSetForLagMultSpace::ComputeIncidentEdges(std::set< EdgeType > & Se, NodeType & v)
+{
+	int n = 0;
+	std::set < EdgeType >::iterator it = Se.begin();
+  for (;it!=Se.end();it++)
+	{
+		if ((*it).first == v | (*it).second == v) n++;
+	}
+	return n;
+}
+
+
+MVertex * FilterLevelSetForLagMultSpace::getNodeWithLowestScore(std::map < NodeType , int > & NodesScore)
+{
+	NodeType v;
+	std::map < NodeType , int >::iterator it = NodesScore.begin();
+	v = (*it).first;
+	for (;it!=NodesScore.end() ; it ++)
+	{
+		if ((*it).second < NodesScore[v]) v = (*it).first ;
+	}
+	return v;
+}
+
+void FilterLevelSetForLagMultSpace::killConnectedEdges (std::map < NodeType , EdgeType > & NodeToEdgeMap, std::set< EdgeType > & Se , std::set< NodeType > & Sn, NodeType v)
+{
+	
+	std::vector < EdgeType > EdgesToErase;
+	std::vector < NodeType > NodesToErase;
+	
+	NodeType v1 = NodeToEdgeMap[v].first;
+	NodeType v2 = NodeToEdgeMap[v].second;
+	
+	std::set < EdgeType >::iterator ite = Se.begin();
+  for (;ite!=Se.end();ite++)
+	{
+		if ((*ite).first == v1 | (*ite).second == v1) EdgesToErase.push_back(*ite);
+		if ((*ite).first == v2 | (*ite).second == v2) EdgesToErase.push_back(*ite);
+	}
+	for (int i = 0 ; i < EdgesToErase.size() ; i ++)
+	{
+		Se.erase(EdgesToErase[i]);
+	}
+	
+	
+	std::set < NodeType >::iterator itn = Sn.begin();
+	for (; itn != Sn.end() ; itn ++)
+	{
+	  if (Se.find(NodeToEdgeMap[(*itn)]) == Se.end()) NodesToErase.push_back(*itn);
+	}
+	for (int i = 0 ; i < NodesToErase.size() ; i ++)
+	{
+		if (NodesToErase[i]->getNum() != v->getNum()) _looser_nodes.insert(NodesToErase[i]);
+		Sn.erase(NodesToErase[i]);
+	}
+	
+}
+
diff --git a/Solver/filters.h b/Solver/filters.h
index 9a5781143c3b0c038d58fd85b146e4390eb30ef4..74fa9615c40eb83765458e2b3eba5f941b8f40a3 100644
--- a/Solver/filters.h
+++ b/Solver/filters.h
@@ -15,6 +15,7 @@
 #include "dofManager.h"
 #include "GModel.h"
 #include "groupOfElements.h"
+#include "DILevelset.h"
 
 class FilterNodeEnriched
 {
@@ -124,21 +125,45 @@ class FilterElementsCutByLevelSet
 class FilterLevelSetForLagMultSpace
 {
 
+	private :
+		
+		typedef MVertex * NodeType;
+		typedef std::pair <NodeType , NodeType > EdgeType;
+		typedef std::pair <EdgeType , double > EdgeScoreType;
+
+	
   private :
 
-		groupOfElements * _g;
+		groupOfElements * _LevelSetElements;
 		std::pair<int,int> _LevelSetEntity;
-		std::set<int> _winner_nodes;
-    std::set<int> _all_nodes;
+		std::set< NodeType > _winner_nodes;
+		std::set< NodeType > _looser_nodes;
+		gLevelset *_ls;
 		
 	private :
 		
+		// decimation algorithm result in _winner_nodes set
 		void SortNodes (void) ;
+		// initialisation of needed sets
+		void fillNodeToEdgeMap(std::map < NodeType , EdgeType > & NodeToEdgeMap, std::set< EdgeType > & Se , std::set< NodeType > & Sn) ;
+		// find edge in the element associate with node
+		EdgeType findEdge(NodeType v, MElement * e);
+		// verify if node belong to edge  // ...normaly has to be done when cutting model ...
+		bool NodeBelongToEdge(NodeType v, EdgeType edge);
+		// compute score
+		void ComputeScore(std::map < NodeType , EdgeType > & NodeToEdgeMap, std::set< EdgeType > & Se, std::set< NodeType > & Sn, std::map < NodeType , int > & NodesScore);
+		// compute number of incident edges in Se to node v
+		int ComputeIncidentEdges(std::set< EdgeType > & Se, NodeType & v);
+		// get lowest  (no need to sort just get the lowest)
+		NodeType getNodeWithLowestScore(std::map < NodeType , int > & NodesScore);
+		// kill connected edges
+		void killConnectedEdges (std::map < NodeType , EdgeType > & NodeToEdgeMap, std::set< EdgeType > & Se , std::set< NodeType > & Sn, NodeType v);
 
   public :
 
-    FilterLevelSetForLagMultSpace(std::pair<int,int> LevelSetEntity, groupOfElements * g) : _LevelSetEntity(LevelSetEntity), _g(g)
+    FilterLevelSetForLagMultSpace(std::pair<int,int> LevelSetEntity , gLevelset *ls) : _LevelSetEntity(LevelSetEntity), _ls(ls)
     {
+			  groupOfElements *_LevelSetElements = new groupOfElements (_LevelSetEntity.first, _LevelSetEntity.second);
 				SortNodes();
     }