diff --git a/examples/bubble/periodic_bubble.py b/examples/bubble/periodic_bubble.py
index 5c088b7376f0118c83bc588ddb62e64ec6ece1b4..cdc9868ceb867afa3a40a56ce11d899b56944dbf 100644
--- a/examples/bubble/periodic_bubble.py
+++ b/examples/bubble/periodic_bubble.py
@@ -110,6 +110,7 @@ def compute(args):
     if (dim==3):
         stretch_diffuse = DirectionalStretchingDiffusion(implementation=impl,
                  name='stretch_diffuse',
+                 pretty_name='sdiff',
                  formulation = args.stretching_formulation,
                  viscosity = mu,
                  velocity  = velo,       
@@ -118,7 +119,8 @@ def compute(args):
                  dt=dt, **extra_op_kwds)
     elif (dim==2):
         stretch_diffuse = DirectionalDiffusion(implementation=impl,
-                 name='stretch_diffuse',
+                 name='diffuse',
+                 pretty_name='diff',
                  coeffs = mu,
                  fields  = vorti,
                  variables = {vorti: npts, mu: npts},
@@ -140,7 +142,7 @@ def compute(args):
 
     #> Operators to dump rho and mu
     io_params = IOParams(filename='fields', frequency=args.dump_freq)
-    dump_fields = HDF_Writer(name='hdf_writer',
+    dump_fields = HDF_Writer(name='dump',
                              io_params=io_params,
                              variables={velo: npts, 
                                         vorti: npts,    
@@ -148,19 +150,19 @@ def compute(args):
                                         mu: npts})
     
     #> Operator to compute the infinite norm of the velocity
-    min_max_U = MinMaxFieldStatistics(name='min_max_U', field=velo,
+    min_max_U = MinMaxFieldStatistics(field=velo,
             Finf=True, implementation=impl, variables={velo:npts},
             **extra_op_kwds)
     #> Operator to compute the infinite norm of the vorticity
-    min_max_W = MinMaxFieldStatistics(name='min_max_W', field=vorti,
+    min_max_W = MinMaxFieldStatistics(field=vorti,
             Finf=True, implementation=impl, variables={vorti:npts},
             **extra_op_kwds)
     #> Operator to track min and max density and viscosity
-    min_max_rho = MinMaxFieldStatistics(name='min_max_rho', field=rho,
+    min_max_rho = MinMaxFieldStatistics(field=rho,
             Fmin=True, Fmax=True,
             implementation=impl, variables={rho:npts},
             **extra_op_kwds)
-    min_max_mu = MinMaxFieldStatistics(name='min_max_mu', field=mu,
+    min_max_mu = MinMaxFieldStatistics(field=mu,
             Fmin=True, Fmax=True,
             implementation=impl, variables={mu:npts},
             **extra_op_kwds)
diff --git a/hysop/core/graph/computational_graph.py b/hysop/core/graph/computational_graph.py
index 596c52735311348ad21501ad2a3d8248a4d43584..8c9d2ab0d6c5c65e6920040b156e1c4b9ca2c7ec 100644
--- a/hysop/core/graph/computational_graph.py
+++ b/hysop/core/graph/computational_graph.py
@@ -1,7 +1,7 @@
 from hysop import __DEBUG__, __VERBOSE__, vprint, dprint
 from hysop.tools.decorators  import debug
 from hysop.tools.types import to_list, to_set
-from hysop.tools.string_utils import framed_str
+from hysop.tools.string_utils import framed_str, strlen
 from hysop.tools.numpywrappers import npw
 from hysop.core.graph.graph import not_implemented, initialized, discretized, \
                               ready, graph_built, not_initialized
@@ -70,7 +70,8 @@ class ComputationalGraph(ComputationalGraphNode):
         sinputs, soutputs = {}, {}
         def sorted_reqs(reqs):
             return sorted(reqs, key=lambda x: \
-                    '{}::{}'.format(x.operator.name, x.field.name))
+                    u'{}::{}'.format(x.operator.pretty_name.decode('utf-8'), 
+                                     x.field.pretty_name.decode('utf-8')))
         for field, mreqs in requirements.input_field_requirements.iteritems():
             for td, reqs in mreqs.requirements.iteritems():
                 for req in reqs:
@@ -79,15 +80,15 @@ class ComputationalGraph(ComputationalGraphNode):
             sin = sinputs.setdefault(td, [])
             for field, reqs in td_reqs.iteritems():
                 for req in sorted_reqs(reqs):
-                    opname = getattr(req.operator, 'name', 'UnknownOperator')
-                    fname  = getattr(req.field,    'name', 'UnknownField')
+                    opname = getattr(req.operator, 'pretty_name', 'UnknownOperator').decode('utf-8')
+                    fname  = getattr(req.field,    'pretty_name', 'UnknownField').decode('utf-8')
                     min_ghosts=req.ghost_str(req.min_ghosts)
                     max_ghosts=req.ghost_str(req.max_ghosts+1)
-                    ghosts = '{}<=ghosts<{}'.format(min_ghosts, max_ghosts)
+                    ghosts = u'{}<=ghosts<{}'.format(min_ghosts, max_ghosts)
                     can_split=req.can_split.view(npw.int8)
-                    basis='{}'.format(','.join(str(basis)[:3] for basis in req.basis)) \
+                    basis=u'{}'.format(u','.join(str(basis)[:3] for basis in req.basis)) \
                             if req.basis else 'ANY' 
-                    tstates='{}'.format(','.join(str(ts) for ts in req.tstates)) \
+                    tstates=u'{}'.format(u','.join(str(ts) for ts in req.tstates)) \
                             if req.tstates else 'ANY'
                     sin.append( (opname, fname, ghosts, basis, tstates) )
         for field, mreqs in requirements.output_field_requirements.iteritems():
@@ -98,35 +99,34 @@ class ComputationalGraph(ComputationalGraphNode):
             sin = soutputs.setdefault(td, [])
             for field, reqs in td_reqs.iteritems():
                 for req in sorted_reqs(reqs):
-                    opname = getattr(req.operator, 'name', 'UnknownOperator')
-                    fname  = getattr(req.field,    'name', 'UnknownField')
+                    opname = getattr(req.operator, 'pretty_name', 'UnknownOperator').decode('utf-8')
+                    fname  = getattr(req.field,    'pretty_name', 'UnknownField').decode('utf-8')
                     min_ghosts=req.ghost_str(req.min_ghosts)
                     max_ghosts=req.ghost_str(req.max_ghosts+1)
-                    ghosts = '{}<=ghosts<{}'.format(min_ghosts, max_ghosts)
+                    ghosts = u'{}<=ghosts<{}'.format(min_ghosts, max_ghosts)
                     can_split=req.can_split.view(npw.int8)
-                    basis='{}'.format(','.join(str(basis)[:3] for basis in req.basis)) \
-                            if req.basis else 'ANY' 
-                    tstates='{}'.format(','.join(str(ts) for ts in req.tstates)) \
-                            if req.tstates else 'ANY'
+                    basis=u'{}'.format(u','.join(str(basis)[:3] for basis in req.basis)) \
+                            if req.basis else u'ANY' 
+                    tstates=u'{}'.format(u','.join(str(ts) for ts in req.tstates)) \
+                            if req.tstates else u'ANY'
                     sin.append( (opname, fname, ghosts, basis, tstates) )
         
-        titles = [[('OPERATOR', 'FIELD', 'GHOSTS', 'BASIS', 'TSTATES')]]
+        titles = [[(u'OPERATOR', u'FIELD', u'GHOSTS', u'BASIS', u'TSTATES')]]
         name_size    = max(len(s[0]) for ss in sinputs.values()+soutputs.values()+titles for s in ss)
         field_size   = max(len(s[1]) for ss in sinputs.values()+soutputs.values()+titles for s in ss)
-        ghosts_size  = max(len(s[2].decode('utf-8').replace(u'\u221e', u' ')) \
-                            for ss in sinputs.values()+soutputs.values()+titles for s in ss)
+        ghosts_size  = max(len(s[2]) for ss in sinputs.values()+soutputs.values()+titles for s in ss)
         basis_size   = max(len(s[3]) for ss in sinputs.values()+soutputs.values()+titles for s in ss)
         tstates_size = max(len(s[4]) for ss in sinputs.values()+soutputs.values()+titles for s in ss)
 
-        template = '\n   {:<{name_size}}   {:^{field_size}}     {:^{ghosts_size}}      {:^{basis_size}}      {:^{tstates_size}}'
+        template = u'\n   {:<{name_size}}   {:^{field_size}}     {:^{ghosts_size}}      {:^{basis_size}}      {:^{tstates_size}}'
         
-        ss= '>INPUTS:'
+        ss= u'>INPUTS:'
         if sinputs:
             for (td, sreqs) in sinputs.iteritems():
                 if isinstance(td, Topology):
-                    ss+='\n {}'.format(td.short_description())
+                    ss+=u'\n {}'.format(td.short_description())
                 else:
-                    ss+='\n {}'.format(td)
+                    ss+=u'\n {}'.format(td)
                 ss+= template.format(*titles[0][0],
                         name_size=name_size, field_size=field_size, ghosts_size=ghosts_size, 
                         basis_size=basis_size, tstates_size=tstates_size)
@@ -136,14 +136,14 @@ class ComputationalGraph(ComputationalGraphNode):
                             name_size=name_size, field_size=field_size, ghosts_size=ghosts_size, 
                             basis_size=basis_size, tstates_size=tstates_size)
         else:
-            ss+=' None'
-        ss+= '\n>OUTPUTS:'
+            ss+=u' None'
+        ss+= u'\n>OUTPUTS:'
         if soutputs:
             for (td, sreqs) in soutputs.iteritems():
                 if isinstance(td, Topology):
-                    ss+='\n {}'.format(td.short_description())
+                    ss+=u'\n {}'.format(td.short_description())
                 else:
-                    ss+='\n {}'.format(td)
+                    ss+=u'\n {}'.format(td)
                 ss+= template.format(*titles[0][0],
                         name_size=name_size, field_size=field_size, ghosts_size=ghosts_size, 
                         basis_size=basis_size, tstates_size=tstates_size)
@@ -153,10 +153,10 @@ class ComputationalGraph(ComputationalGraphNode):
                             name_size=name_size, field_size=field_size, ghosts_size=ghosts_size, 
                             basis_size=basis_size, tstates_size=tstates_size)
         else:
-            ss+=' None'
+            ss+=u' None'
 
-        title = ' ComputationalGraph {} field requirements report '.format(self.name)
-        return '\n{}\n'.format(framed_str(title=title, msg=ss))
+        title = u' ComputationalGraph {} field requirements report '.format(self.pretty_name.decode('utf-8'))
+        return u'\n{}\n'.format(framed_str(title=title, msg=ss)).encode('utf-8')
 
     def domain_report(self):
         domains = self.get_domains()
@@ -164,84 +164,126 @@ class ComputationalGraph(ComputationalGraphNode):
         for (domain,operators) in domains.iteritems():
             if (domain is None):
                 continue
-            for op in sorted(operators, key=lambda x: x.name):
-                finputs = ','.join( sorted([f.name for f in op.input_fields    if f.domain is domain]))
-                foutputs =','.join( sorted([f.name for f in op.output_fields   if f.domain is domain]))
-                pinputs = ','.join( sorted([p for p in op.input_params]))
-                poutputs =','.join( sorted([p for p in op.output_params]))
-                infields  = '[{}]'.format(finputs)  if finputs  else ''
-                outfields = '[{}]'.format(foutputs) if foutputs else ''
-                inparams  = '[{}]'.format(pinputs)  if pinputs  else ''
-                outparams = '[{}]'.format(poutputs) if poutputs else ''
+            for op in sorted(operators, key=lambda x: x.pretty_name):
+                finputs = u','.join( sorted([f.pretty_name.decode('utf-8') for f in op.input_fields  if f.domain is domain]))
+                foutputs =u','.join( sorted([f.pretty_name.decode('utf-8') for f in op.output_fields if f.domain is domain]))
+                pinputs = u','.join( sorted([p.pretty_name.decode('utf-8') for p in op.input_params.values()]))
+                poutputs =u','.join( sorted([p.pretty_name.decode('utf-8') for p in op.output_params.values()]))
+                infields  = u'[{}]'.format(finputs)  if finputs  else u''
+                outfields = u'[{}]'.format(foutputs) if foutputs else u''
+                inparams  = u'[{}]'.format(pinputs)  if pinputs  else u''
+                outparams = u'[{}]'.format(poutputs) if poutputs else u''
                         
-                inputs  = '{}{}{}'.format(infields,  'x' if infields  and inparams  else '', inparams)
-                outputs = '{}{}{}'.format(outfields, 'x' if outfields and outparams else '', outparams)
+                inputs  = u'{}{}{}'.format(infields,  u'x' if infields  and inparams  else u'', inparams)
+                outputs = u'{}{}{}'.format(outfields, u'x' if outfields and outparams else u'', outparams)
                 
-                if inputs == '':
-                    inputs='no inputs'
-                if outputs == '':
-                    outputs='no outputs'
-                ops.setdefault(domain, []).append( (op.name, inputs, outputs, type(op).__name__) )
+                if inputs == u'':
+                    inputs=u'no inputs'
+                if outputs == u'':
+                    outputs=u'no outputs'
+                ops.setdefault(domain, []).append( (op.pretty_name.decode('utf-8'), inputs, outputs, type(op).__name__) )
 
         if (None in domains):
             operators = domains[None]
-            for op in sorted(operators, key=lambda x: x.name):
-                pinputs = ','.join( sorted([p for p in op.input_params]))
-                poutputs =','.join( sorted([p for p in op.output_params]))
-                inparams  = '[{}]'.format(pinputs) if pinputs  else ''
-                outparams = '[{}]'.format(poutputs) if poutputs else ''
-
-                inputs='{}'.format(inparams)
-                outputs='{}'.format(outparams)
+            for op in sorted(operators, key=lambda x: x.pretty_name):
+                pinputs = u','.join( sorted([p.pretty_name.decode('utf-8') for p in op.input_params.values()]))
+                poutputs =u','.join( sorted([p.pretty_name.decode('utf-8') for p in op.output_params.values()]))
+                inparams  = u'[{}]'.format(pinputs) if pinputs  else ''
+                outparams = u'[{}]'.format(poutputs) if poutputs else ''
+
+                inputs=u'{}'.format(inparams)
+                outputs=u'{}'.format(outparams)
                 if inputs == '':
-                    inputs='no inputs'
+                    inputs=u'no inputs'
                 if outputs == '':
-                    outputs='no outputs'
-                ops.setdefault(None, []).append( (op.name, inputs, outputs, type(op).__name__) )
+                    outputs=u'no outputs'
+                ops.setdefault(None, []).append( (op.pretty_name.decode('utf-8'), inputs, outputs, type(op).__name__) )
         
-        name_size = max(len(s[0]) for ss in ops.values() for s in ss)
-        in_size   = max(len(s[1]) for ss in ops.values() for s in ss)
-        out_size  = max(len(s[2]) for ss in ops.values() for s in ss)
-        type_size = max(len(s[3]) for ss in ops.values() for s in ss)
+        name_size = max(strlen(s[0]) for ss in ops.values() for s in ss)
+        in_size   = max(strlen(s[1]) for ss in ops.values() for s in ss)
+        out_size  = max(strlen(s[2]) for ss in ops.values() for s in ss)
+        type_size = max(strlen(s[3]) for ss in ops.values() for s in ss)
 
-        ss = ''
+        ss = u''
         for (domain,dops) in ops.iteritems():
             if (domain is None):
                 continue
-            ss += '\n>{}'.format(domain.short_description())
-            ss += '\n   {:<{name_size}}  {:<{in_size}}       {:<{out_size}}    {:<{type_size}}'.format(
+            ss += u'\n>{}'.format(domain.short_description())
+            ss += u'\n   {:<{name_size}}  {:<{in_size}}       {:<{out_size}}    {:<{type_size}}'.format(
                         'OPERATOR', 'INPUTS', 'OUTPUTS', 'OPERATOR TYPE',
                         name_size=name_size, in_size=in_size, 
                         out_size=out_size, type_size=type_size)
             for (opname, inputs, outputs, optype) in dops:
-                ss += '\n   {:<{name_size}}  {:<{in_size}}  ->   {:<{out_size}}    {:<{type_size}}'.format(
+                ss += u'\n   {:<{name_size}}  {:<{in_size}}  ->   {:<{out_size}}    {:<{type_size}}'.format(
                         opname, inputs, outputs, optype,
                         name_size=name_size, in_size=in_size,
                         out_size=out_size, type_size=type_size)
         if (None in domains):
-            ss += '\n>Domainless operators:'
-            ss += '\n   {:<{name_size}}  {:<{in_size}}       {:<{out_size}}    {:<{type_size}}'.format(
+            ss += u'\n>Domainless operators:'
+            ss += u'\n   {:<{name_size}}  {:<{in_size}}       {:<{out_size}}    {:<{type_size}}'.format(
                         'OPERATOR', 'INPUTS', 'OUTPUTS', 'OPERATOR TYPE',
                         name_size=name_size, in_size=in_size, 
                         out_size=out_size, type_size=type_size)
             for (opname, inputs, outputs, optype) in ops[None]:
-                ss += '\n   {:<{name_size}}  {:<{in_size}}  ->   {:<{out_size}}    {:<{type_size}}'.format(
+                ss += u'\n   {:<{name_size}}  {:<{in_size}}  ->   {:<{out_size}}    {:<{type_size}}'.format(
                         opname, inputs, outputs, optype,
                         name_size=name_size, in_size=in_size,
                         out_size=out_size, type_size=type_size)
         
-        title=' ComputationalGraph {} domain and operator report '.format(self.name)
-        return '\n{}\n'.format(framed_str(title=title, msg=ss[1:]))
+        title=u' ComputationalGraph {} domain and operator report '.format(self.pretty_name.decode('utf-8'))
+        return u'\n{}\n'.format(framed_str(title=title, msg=ss[1:])).encode('utf-8')
             
 
     def topology_report(self):
         ss=''
         for (backend,topologies) in self.get_topologies().iteritems():
-            ss += '\n {}:'.format(backend.short_description())
-            ss += '\n  *'+'\n  *'.join(t.short_description()
+            ss += u'\n {}:'.format(backend.short_description())
+            ss += u'\n  *'+'\n  *'.join(t.short_description()
                 for t in sorted(topologies, key=lambda x: x.id))
-        title = ' ComputationalGraph {} topology report '.format(self.name)
-        return '\n{}\n'.format(framed_str(title=title, msg=ss[1:]))
+        title = u' ComputationalGraph {} topology report '.format(self.pretty_name.decode('utf-8'))
+        return u'\n{}\n'.format(framed_str(title=title, msg=ss[1:]))
+
+    def variable_report(self):
+        reduced_graph = self.reduced_graph
+        operators = reduced_graph.vertex_properties['operators']
+        fields = self.fields
+        
+        topologies = {}
+        for field in self.fields:
+            field_topologies = {}
+            for (i,vid) in enumerate(self.sorted_nodes):
+                vertex = reduced_graph.vertex(vid)
+                op     = operators[vertex]
+                if field in op.input_fields:
+                    topo = op.input_fields[field]
+                    field_topologies.setdefault(topo, []).append(op)
+                if field in op.output_fields:
+                    topo = op.output_fields[field]
+                    field_topologies.setdefault(topo, []).append(op)
+            for topo in field_topologies.keys():
+                pnames = set(op.pretty_name.decode('utf-8') for op in field_topologies[topo]) 
+                sops=u', '.join(sorted(pnames))
+                entries = (str(topo.backend.kind).lower(), topo.tag, sops)
+                topologies.setdefault(field, []).append(entries)
+
+        titles = [[(u'BACKEND', u'TOPOLOGY', u'OPERATORS')]]
+        backend_size = max(len(s[0]) for ss in topologies.values()+titles for s in ss)
+        topo_size    = max(len(s[1]) for ss in topologies.values()+titles for s in ss)
+        template = u'\n   {:<{backend_size}}   {:<{topo_size}}   {}'
+        sizes = {'backend_size': backend_size,
+                 'topo_size': topo_size}
+        
+        ss = u''
+        for field in sorted(self.fields, key=lambda x: x.tag):
+            ss += u'\n>FIELD {}::{}'.format(field.name, field.pretty_name.decode('utf-8'))
+            ss += template.format(*titles[0][0], **sizes)
+            field_topologies = topologies[field]
+            for entries in sorted(field_topologies, key=lambda x: x[0]):
+                ss += template.format(*entries, **sizes)
+
+        title = u' ComputationalGraph {} fields report '.format(self.pretty_name.decode('utf-8'))
+        ss = u'\n{}\n'.format(framed_str(title=title, msg=ss[1:]))
+        return ss.encode('utf-8')
     
     def operator_report(self):
         reduced_graph = self.reduced_graph
@@ -251,24 +293,30 @@ class ComputationalGraph(ComputationalGraphNode):
             vertex = reduced_graph.vertex(vid)
             op     = operators[vertex]
 
-            finputs   = ','.join( sorted(['{}.{}'.format(f.name,t.tag) for (f,t) in op.input_fields.iteritems()]))
-            foutputs  = ','.join( sorted(['{}.{}'.format(f.name,t.tag) for (f,t) in op.output_fields.iteritems()]))
-            pinputs   = ','.join( sorted([p for p in op.input_params]))
-            poutputs  = ','.join( sorted([p for p in op.output_params]))
-
-            infields  = '[{}]'.format(finputs)  if finputs  else ''
-            outfields = '[{}]'.format(foutputs) if foutputs else ''
-            inparams  = '[{}]'.format(pinputs)  if pinputs  else ''
-            outparams = '[{}]'.format(poutputs) if poutputs else ''
+            finputs   = u','.join( sorted([u'{}.{}'.format(f.pretty_name.decode('utf-8'),
+                                                           t.pretty_tag.decode('utf-8'))
+                                            for (f,t) in op.input_fields.iteritems()]))
+            foutputs  = u','.join( sorted([u'{}.{}'.format(f.pretty_name.decode('utf-8'),
+                                                           t.pretty_tag.decode('utf-8'))
+                                            for (f,t) in op.output_fields.iteritems()]))
+            pinputs   = u','.join( sorted([p.pretty_name.decode('utf-8') 
+                                            for p in op.input_params.values()]))
+            poutputs  = u','.join( sorted([p.pretty_name.decode('utf-8') 
+                                            for p in op.output_params.values()]))
+
+            infields  = u'[{}]'.format(finputs)  if finputs  else u''
+            outfields = u'[{}]'.format(foutputs) if foutputs else u''
+            inparams  = u'[{}]'.format(pinputs)  if pinputs  else u''
+            outparams = u'[{}]'.format(poutputs) if poutputs else u''
                             
-            inputs  = '{}{}{}'.format(infields,  'x' if infields  and inparams  else '', inparams)
-            outputs = '{}{}{}'.format(outfields, 'x' if outfields and outparams else '', outparams)
+            inputs  = u'{}{}{}'.format(infields,  u'x' if infields  and inparams  else u'', inparams)
+            outputs = u'{}{}{}'.format(outfields, u'x' if outfields and outparams else u'', outparams)
             if inputs == '':
-                inputs='no inputs'
+                inputs=u'no inputs'
             if outputs == '':
-                outputs='no outputs'
+                outputs=u'no outputs'
 
-            ops.append( (op.name, inputs, outputs, type(op).__name__) )
+            ops.append( (op.pretty_name.decode('utf-8'), inputs, outputs, type(op).__name__) )
         
         isize     = len(self.sorted_nodes)
         isize     = int(npw.ceil(npw.log10(isize)))
@@ -277,20 +325,20 @@ class ComputationalGraph(ComputationalGraphNode):
         out_size  = max(len(s[2]) for s in ops)
         type_size = max(len(s[3]) for s in ops)
 
-        ss = '  {:<{isize}}  {:<{name_size}}  {:<{in_size}}       {:<{out_size}}    {:<{type_size}}'.format(
+        ss = u'  {:<{isize}}  {:<{name_size}}  {:<{in_size}}       {:<{out_size}}    {:<{type_size}}'.format(
                     'ID', 'OPERATOR', 'INPUTS', 'OUTPUTS', 'OPERATOR TYPE',
                     isize=isize,
                     name_size=name_size, in_size=in_size, 
                     out_size=out_size, type_size=type_size)
         for i, (opname, inputs, outputs, optype) in enumerate(ops):
-            ss += '\n  {:>{isize}}  {:<{name_size}}  {:<{in_size}}  ->   {:<{out_size}}    {:<{type_size}}'.format(
+            ss += u'\n  {:>{isize}}  {:<{name_size}}  {:<{in_size}}  ->   {:<{out_size}}    {:<{type_size}}'.format(
                     i, opname, inputs, outputs, optype,
                     isize=isize,
                     name_size=name_size, in_size=in_size,
                     out_size=out_size, type_size=type_size)
         
-        title = ' ComputationalGraph {} discrete operator report '.format(self.name)
-        return '\n{}\n'.format(framed_str(title=title, msg=ss))
+        title = u' ComputationalGraph {} discrete operator report '.format(self.pretty_name.decode('utf-8'))
+        return u'\n{}\n'.format(framed_str(title=title, msg=ss)).encode('utf-8')
 
     def get_domains(self):
         domains = {}
@@ -330,8 +378,8 @@ class ComputationalGraph(ComputationalGraphNode):
     def available_methods(self):
         avail_methods = {}
         if not self.nodes:
-            msg='No nodes present in ComputationalGraph {}.'.format(self.name)
-            raise RuntimeError(msg)
+            msg=u'No nodes present in ComputationalGraph {}.'.format(self.pretty_name.decode('utf-8'))
+            raise RuntimeError(msg.encode('utf-8'))
         for node in self.nodes:
             for (k,v) in node.available_methods().iteritems():
                 v = to_set(v)
@@ -358,8 +406,8 @@ class ComputationalGraph(ComputationalGraphNode):
         if is_root:
             self.pre_initialize(**kwds)
 
-        msg='ComputationalGraph {} is empty.'
-        assert len(self.nodes) > 0, msg.format(self.name)
+        msg=u'ComputationalGraph {} is empty.'
+        assert len(self.nodes) > 0, msg.format(self.pretty_name.decode('utf-8')).encode('utf-8')
         
         for node in self.nodes:
             node.pre_initialize(**kwds)
@@ -470,6 +518,7 @@ class ComputationalGraph(ComputationalGraphNode):
 
         if (self.is_root and __VERBOSE__) or __DEBUG__ or self.__FORCE_REPORTS__:
             print self.topology_report()
+            print self.variable_report()
             print self.operator_report()
 
     @debug
@@ -542,7 +591,7 @@ class ComputationalGraph(ComputationalGraphNode):
         
         if self.is_root:
             input_discrete_fields = {}
-            for field,topo in self.input_fields.iteritems():
+            for (field,topo) in self.input_fields.iteritems():
                 istate = self.initial_input_topology_states[field][1]
                 istate = istate.copy(is_read_only=False) # problem inputs are writeable for initialization
                 dfield = field.discretize(topo, istate)
@@ -577,10 +626,10 @@ class ComputationalGraph(ComputationalGraphNode):
                 wp = op.get_work_properties()
                 requests += op.get_work_properties()
         if __DEBUG__ or (__VERBOSE__ and self.level==0) or self.__FORCE_REPORTS__:
-            srequests = str(requests)
-            ss = (srequests if (srequests != '') else ' *no extra work requested*')
-            title= ' ComputationalGraph {} work properties report '.format(self.name)
-            vprint('\n{}\n'.format(framed_str(title=title, msg=ss)))
+            srequests = requests.sreport()
+            ss = (srequests if (srequests != u'') else u' *no extra work requested*')
+            title= u' ComputationalGraph {} work properties report '.format(self.pretty_name.decode('utf-8'))
+            vprint(u'\n{}\n'.format(framed_str(title=title, msg=ss)).encode('utf-8'))
         return requests 
     
     @debug
diff --git a/hysop/core/graph/graph_builder.py b/hysop/core/graph/graph_builder.py
index 75d48a01157f339dc3196668196ca497e06ad837..cf069e9cdec77e769b7daf4fde1d71ae7e27981f 100644
--- a/hysop/core/graph/graph_builder.py
+++ b/hysop/core/graph/graph_builder.py
@@ -164,7 +164,7 @@ class GraphBuilder(object):
         target_node = self.target_node
 
         current_level = self.current_level
-        outputs_are_inputs = self.outputs_are_inputs 
+        outputs_are_inputs = self.outputs_are_inputs
 
         graph = self.graph
         vertex_properties = self.vertex_properties
@@ -172,8 +172,8 @@ class GraphBuilder(object):
         
         parameter_handler = self.__ParameterHandler(graph, edge_properties, vertex_properties)
 
-        input_fields    = self.input_fields
-        output_fields   = self.output_fields
+        input_fields  = self.input_fields
+        output_fields = self.output_fields
         input_params  = self.input_params
         output_params = self.output_params
         input_topology_states  = self.input_topology_states
@@ -199,7 +199,7 @@ class GraphBuilder(object):
             raise RuntimeError(msg)
 
         # iterate over ComputationalNodes
-        for node_id,node in enumerate(target_node.nodes):
+        for (node_id, node) in enumerate(target_node.nodes):
             dprint(' >Handling node {}: {}'.format(node_id, node.name) )
 
             # Recursively build graph.
@@ -213,12 +213,12 @@ class GraphBuilder(object):
             # iterate over subgraph operators
             for (opvertex, op) in zip(node_vertices,node_ops):
                 dprint('  *{} ({})'.format(op.name, type(op)))
-                opname  = op.name
-                oppname = op.pretty_name
-                iparams = op.input_params
-                oparams = op.output_params
-                ifields = op.input_fields
-                ofields = op.output_fields
+                opname   = op.name
+                oppname  = op.pretty_name
+                iparams  = op.input_params
+                oparams  = op.output_params
+                ifields  = op.input_fields
+                ofields  = op.output_fields
                 backends = op.supported_backends()
                 field_requirements = op._field_requirements
                 
@@ -231,7 +231,7 @@ class GraphBuilder(object):
                 for (ifield, itopo) in ifields.iteritems():
                     if (itopo is not None):
                         continue
-                    # look for ifield usage till now
+                    # look for ifield usage untill now
                     if (ifield in ofields) and (ofields[ifield] is not None) and (ofields[ifield].backend.kind in backends):
                         ifields[ifield] = ofields[ifield]
                     elif (ifield not in self.topology_states):
@@ -564,6 +564,9 @@ class GraphBuilder(object):
         operators     = reduced_graph.vertex_properties['operators']
         nodes = [ operators[reduced_graph.vertex(vid)] for vid in self.sorted_nodes ]
         return nodes
+        import sys
+        sys.exit(1)
+
         
     def build_subgraph(self, node, current_level, **kwds):
         node_ops = []
diff --git a/hysop/core/graph/node_generator.py b/hysop/core/graph/node_generator.py
index 79b7a06c0542b735c1e7dfec56b6b67b2c61ecae..4063482fdfb7e9d944aa786acb5ffabb0228fdc6 100644
--- a/hysop/core/graph/node_generator.py
+++ b/hysop/core/graph/node_generator.py
@@ -1,6 +1,7 @@
 from abc import ABCMeta, abstractmethod
 from hysop import dprint
 from hysop.tools.decorators import debug
+from hysop.tools.types import first_not_None
 from hysop.core.graph.computational_node import ComputationalGraphNode
 
 class ComputationalGraphNodeGenerator(object):
@@ -11,9 +12,10 @@ class ComputationalGraphNodeGenerator(object):
     __metaclass__ = ABCMeta
 
     @debug
-    def __init__(self, name=None, **kwds):
+    def __init__(self, name=None, pretty_name=None, **kwds):
         super(ComputationalGraphNodeGenerator, self).__init__(**kwds)
         self.name = name or self.__class__.__name__
+        self.pretty_name = first_not_None(pretty_name, self.name)
         self.nodes     = []
         self.generated = False
 
diff --git a/hysop/core/memory/memory_request.py b/hysop/core/memory/memory_request.py
index e4d8def1c1616307240623882a603ee4a1514497..b006ba955b09216dac8143af28c4ef75d3b7ffbd 100644
--- a/hysop/core/memory/memory_request.py
+++ b/hysop/core/memory/memory_request.py
@@ -415,7 +415,7 @@ class MultipleOperatorMemoryRequests(object):
                 buffers = tuple([b.handle for b in buffers])
         return buffers
 
-    def __str__(self):
+    def sreport(self):
         all_requests = {}
         for (backend, backend_requests) in self._all_requests_per_backend.iteritems():
             total=0
@@ -423,7 +423,7 @@ class MultipleOperatorMemoryRequests(object):
                 op_requests = backend_requests[op]
                 sop_request = all_requests.setdefault(backend, {}).setdefault(op, [])
                 local_total=0
-                opname='{}'.format(op.name)
+                opname=u'{}'.format(op.pretty_name.decode('utf-8'))
                 for req in op_requests:
                     sop_request.append((opname,)+req.stuple())
                     local_total+=req.max_bytes()
@@ -432,35 +432,35 @@ class MultipleOperatorMemoryRequests(object):
         
         if len(all_requests):
             sizes = {}
-            template = '\n'
-            titles=('OPERATOR', 'REQUEST_ID', 'SIZE', 'COMPONENTS', 'SHAPE', 'DTYPE', 'ALIGNMENT')
+            template = u'\n'
+            titles=(u'OPERATOR', u'REQUEST_ID', u'SIZE', u'COMPONENTS', u'SHAPE', u'DTYPE', u'ALIGNMENT')
             for (i,k) in enumerate(titles): 
                 k=k.lower()
-                template += '    '
+                template += u'    '
                 size = max(len(req[i]) for breqs in all_requests.values() for reqs in breqs.values() for req in reqs)
                 size = max(size, len(k))
-                name=k+'_len'
+                name=k+u'_len'
                 sizes[name] = size
-                template += '{:'+('<' if i==0 else '^')+'{'+name+'}}'
+                template += u'{:'+(u'<' if i==0 else u'^')+u'{'+name+u'}}'
             
             ss=''
             for (backend, backend_srequests) in all_requests.iteritems():
                 kind = backend.kind 
                 if (kind == Backend.OPENCL):
-                    precision = ' on device {}'.format(backend.device.name.strip())
+                    precision = u' on device {}'.format(backend.device.name.strip())
                 else:
-                    precision = ''
-                ss+= '\n {}{}:'.format(backend.full_tag, precision)
+                    precision = u''
+                ss+= u'\n {}{}:'.format(backend.full_tag, precision)
                 ss+= template.format(*titles, **sizes)
                 for op in sorted(backend_srequests.keys(), key=lambda op: op.name):
                     sop_reqs = backend_srequests[op]
                     for sreq in sop_reqs:
                         ss+= template.format(*sreq, **sizes)
-                ss +='\n  Total extra work buffers requested: {} ({})'.format(
+                ss +=u'\n  Total extra work buffers requested: {} ({})'.format(
                         bytes2str(total,decimal=False),
                         bytes2str(total,decimal=True))
-                ss += '\n'
+                ss += u'\n'
             return ss[1:-1]
         else:
-            return ' No extra buffers have been requested.'
+            return u' No extra buffers have been requested.'
         
diff --git a/hysop/fields/default_fields.py b/hysop/fields/default_fields.py
index 0eea67820ef3c44028dfc524d87c2941791e82b0..a7c6c2559234596e36891533acd34cd6a9f762a7 100644
--- a/hysop/fields/default_fields.py
+++ b/hysop/fields/default_fields.py
@@ -5,7 +5,7 @@ from hysop.fields.continuous_field import Field
 def VelocityField(domain, name=None, pretty_name=None, 
                     is_vector=True, **kwds):
     name        = first_not_None(name, 'U')
-    pretty_name = first_not_None(pretty_name, 'U')
+    pretty_name = first_not_None(pretty_name, greak[20])
     is_vector   = first_not_None(is_vector, True)
     return Field(domain=domain, name=name, pretty_name=pretty_name, 
             is_vector=is_vector, **kwds)
diff --git a/hysop/fields/field_requirements.py b/hysop/fields/field_requirements.py
index 48c9d26417de411c1db39131f0a4a21b5c098b06..0c588ed16dcb0f49e3735c25c94e4bb85d18c9a7 100644
--- a/hysop/fields/field_requirements.py
+++ b/hysop/fields/field_requirements.py
@@ -111,7 +111,7 @@ class DiscreteFieldRequirements(object):
     def ghost_str(self, array):
         inf = u'+\u221e'
         vals = [u''+str(x) if np.isfinite(x) else inf for x in array]
-        return u'[{}]'.format(u','.join(vals)).encode('utf-8').strip()
+        return u'[{}]'.format(u','.join(vals)).strip()
 
     def __str__(self):
         
diff --git a/hysop/operator/adapt_timestep.py b/hysop/operator/adapt_timestep.py
index 4cfbb51210800df770a752291b1b5c38ea745392..0c8ff73ac5a41819c8070a7e56911e0946e67474 100755
--- a/hysop/operator/adapt_timestep.py
+++ b/hysop/operator/adapt_timestep.py
@@ -126,7 +126,10 @@ class CflTimestepCriteria(TimestepCriteria):
         dx = self.dx
         Finf = tuple(self.Finf().tolist())
         assert len(dx) == len(Finf)
-        dt = cfl / npw.max(npw.divide(Finf, dx))
+        if npw.any(npw.divide(Finf, dx)==0):
+            dt = cfl*npw.inf
+        else:
+            dt = cfl / npw.max(npw.divide(Finf, dx))
         return dt
     
     def compute_cfl(self, dt):
@@ -195,7 +198,10 @@ class AdvectionTimestepCriteria(TimestepCriteria):
         lcfl = self.lcfl
         if (criteria is AdvectionCriteria.W_INF):
             Finf = self.Finf()
-            return lcfl / npw.max(Finf)
+            if npw.max(Finf)==0:
+                return lcfl*npw.inf
+            else:
+                return lcfl / npw.max(Finf)
         elif (criteria is AdvectionCriteria.GRAD_U):
             gradFinf = self.gradFinf()
             if (gradFinf.ndim == 2):
diff --git a/hysop/operator/base/min_max.py b/hysop/operator/base/min_max.py
index daabf3cfa22f39744bcf4ce44b0472e18347cffc..edd7131670c6fd2cb1bf248e3e6340bab1c5b808 100644
--- a/hysop/operator/base/min_max.py
+++ b/hysop/operator/base/min_max.py
@@ -38,7 +38,7 @@ class MinMaxFieldStatisticsBase(object):
             raise ValueError(msg)
         
         pbasename  = first_not_None(pbasename,  field.name)
-        ppbasename = first_not_None(ppbasename, pbasename)
+        ppbasename = first_not_None(ppbasename, field.pretty_name.decode('utf-8'), pbasename)
         
         def make_param(k, quiet):
             return TensorParameter(name=names[k], pretty_name=pretty_names[k],
@@ -80,7 +80,8 @@ class MinMaxFieldStatisticsBase(object):
     @debug
     def __init__(self, field, components=None, coeffs=None,
             Fmin=None, Fmax=None, Finf=None, all_quiet=None,
-            name=None, pbasename=None, ppbasename=None,
+            name=None, pretty_name=None,
+            pbasename=None, ppbasename=None,
             variables=None, **kwds):
         """
         Initialize a MinMaxField Statistics operator frontend.
@@ -118,6 +119,8 @@ class MinMaxFieldStatisticsBase(object):
             Set all autogenerated TensorParameter to be quiet.
         name: str, optional
             Name of this operator.
+        pretty_name: str, optional
+            Pretty name of this operator.
         pbasename: str, optional
             Parameters basename for created parameters.
             Defaults to field.name.
@@ -160,10 +163,11 @@ class MinMaxFieldStatisticsBase(object):
         check_instance(ppbasename, str, allow_none=True)
         check_instance(all_quiet, bool, allow_none=True)
 
-        coeffs     = first_not_None(coeffs, {})
-        name       = first_not_None(name, 'MinMax[{}]'.format(field.name))
-        variables  = first_not_None(variables, {field: None})
-        all_quiet  = first_not_None(all_quiet, False)
+        coeffs      = first_not_None(coeffs, {})
+        name        = first_not_None(name, 'MinMax[{}]'.format(field.name))
+        pretty_name = first_not_None(pretty_name, 'MinMax({})'.format(field.pretty_name))
+        variables   = first_not_None(variables, {field: None})
+        all_quiet   = first_not_None(all_quiet, False)
         
         parameters = self.build_parameters(field=field, components=components, 
                 all_quiet=all_quiet, Fmin=Fmin, Fmax=Fmax, Finf=Finf,
@@ -172,12 +176,14 @@ class MinMaxFieldStatisticsBase(object):
         output_params = { p.name: p for p in parameters.values() if (p is not None) }
         
         if MinMaxDerivativeStatisticsBase in self.__class__.__mro__:
-            super(MinMaxFieldStatisticsBase, self).__init__(name=name,
+            super(MinMaxFieldStatisticsBase, self).__init__(
+                    name=name, pretty_name=pretty_name,
                     variables=variables, output_params=output_params, **kwds)
             self.has_derivative = True
         else:
             input_fields = {field: variables[field] }
-            super(MinMaxFieldStatisticsBase, self).__init__(name=name,
+            super(MinMaxFieldStatisticsBase, self).__init__(
+                    name=name, pretty_name=pretty_name,
                     input_fields=input_fields, output_params=output_params, **kwds)
             self.has_derivative = False
 
@@ -237,7 +243,8 @@ class MinMaxDerivativeStatisticsBase(MinMaxFieldStatisticsBase):
             derivative=None, component=None, direction=None,
             out_component=None, scaling_view=None, 
             Fmin=None, Fmax=None, Finf=None, coeffs=None, all_quiet=False,
-            name=None, pbasename=None, ppbasename=None,
+            name=None, pretty_name=None,
+            pbasename=None, ppbasename=None,
             variables=None, **kwds):
         """
         Initialize an MinMaxDerivativeStatisticsBase.
@@ -333,6 +340,8 @@ class MinMaxDerivativeStatisticsBase(MinMaxFieldStatisticsBase):
             each components. If not given, defaults to 1 for all statistics.
         name: str, optional
             Name of this operator.
+        pretty_name: str, optional
+            Pretty name of this operator.
         pbasename: str, optional
             Parameters basename for created parameters.
             Defaults to field.name.
@@ -376,7 +385,8 @@ class MinMaxDerivativeStatisticsBase(MinMaxFieldStatisticsBase):
 
         super(MinMaxDerivativeStatisticsBase, self).__init__(field=dF, components=(out_component,),
                 coeffs=coeffs, Fmin=Fmin, Fmax=Fmax, Finf=Finf, 
-                name=name, pbasename=pbasename, variables=variables,
+                name=name, pretty_name=pretty_name,
+                pbasename=pbasename, variables=variables,
                 F=F, dF=dF, A=A, 
                 derivative=derivative, component=component, direction=direction,
                 out_component=out_component, scaling_view=scaling_view, **kwds)
diff --git a/hysop/operator/base/redistribute_operator.py b/hysop/operator/base/redistribute_operator.py
index fdeb3908a93f72fd42845abb1ffc0c706e82df19..a26ec479d02338a6136a4f40781a59ee2d8a4a0a 100644
--- a/hysop/operator/base/redistribute_operator.py
+++ b/hysop/operator/base/redistribute_operator.py
@@ -1,7 +1,8 @@
 
 from abc import ABCMeta, abstractmethod
 from hysop.tools.decorators import debug, not_implemented
-from hysop.tools.types import check_instance, to_set
+from hysop.tools.types import check_instance, to_set, first_not_None
+from hysop.tools.sympy_utils import subscript
 from hysop.constants import Backend
 from hysop.core.graph.computational_operator import ComputationalGraphOperator
 from hysop.topology.topology import Topology
@@ -30,7 +31,8 @@ class RedistributeOperatorBase(ComputationalGraphOperator):
         """
         return Backend.all
 
-    def __init__(self, variable, source_topo, target_topo, components=None, **kwds):
+    def __init__(self, variable, source_topo, target_topo, components=None, 
+                    name=None, pretty_name=None, **kwds):
         """
         Parameters
         ----------
@@ -40,8 +42,12 @@ class RedistributeOperatorBase(ComputationalGraphOperator):
             source mesh topology
         target_topo: :class:`~hysop.topology.topology.Topology` 
             target mesh topology
-        components: int or list of ints 
+        components: int or list of ints, optional
             which component of the field must be distributed (default = all)
+        name: str, optional
+            name of this operator
+        pretty_name: str, optional
+            pretty name of this operator
         """
         check_instance(variable, Field)
         check_instance(source_topo, Topology)
@@ -53,7 +59,21 @@ class RedistributeOperatorBase(ComputationalGraphOperator):
 
         input_fields  = {variable: source_topo}
         output_fields = {variable: target_topo}
-        super(RedistributeOperatorBase, self).__init__(input_fields=input_fields, 
+
+        default_name = 'R_{}_{},{}'.format(variable.name, source_topo.id, target_topo.id)
+
+        default_pname = u'R{}{}{}{}'.format(variable.pretty_name.decode('utf-8'),
+                                          subscript(source_topo.id),
+                                          u'\u2192',
+                                          subscript(target_topo.id))
+        default_pname = default_pname.encode('utf-8')
+
+        pretty_name = first_not_None(pretty_name, name, default_pname)
+        name        = first_not_None(name, default_name)
+
+        super(RedistributeOperatorBase, self).__init__(
+                name=name, pretty_name=pretty_name,
+                input_fields=input_fields, 
                 output_fields=output_fields, **kwds)
         
         self.variable    = variable
diff --git a/hysop/operator/base/transpose_operator.py b/hysop/operator/base/transpose_operator.py
index c6f0ea1dd066b6b9ce7eb487f7936218c861d1d2..71ceedf4d025f611536e1c1e81d6e0ccf8093dd0 100644
--- a/hysop/operator/base/transpose_operator.py
+++ b/hysop/operator/base/transpose_operator.py
@@ -54,7 +54,8 @@ class TransposeOperatorBase(object):
         input_fields  = { input_field:  variables[input_field] }
         output_fields = { output_field: variables[output_field] }
         
-        super(TransposeOperatorBase, self).__init__(input_fields=input_fields,
+        super(TransposeOperatorBase, self).__init__(
+                input_fields=input_fields,
                 output_fields=output_fields, **kwds)
 
         self.input_field = input_field
diff --git a/hysop/operator/directional/directional.py b/hysop/operator/directional/directional.py
index ab3e57b8e02377403f599a19813765f7f46a8c5a..1616d1279849ebc711f6f21fa8479cc84ba3b709 100644
--- a/hysop/operator/directional/directional.py
+++ b/hysop/operator/directional/directional.py
@@ -1,7 +1,8 @@
 
 from abc import ABCMeta, abstractmethod
-from hysop.tools.types import check_instance, to_list
+from hysop.tools.types import check_instance, to_list, first_not_None
 from hysop.tools.decorators  import debug, static_vars
+from hysop.tools.sympy_utils import subscript
 from hysop.constants import Implementation, DirectionLabels, TranspositionState
 from hysop.core.graph.graph import generated, not_implemented
 from hysop.core.graph.node_generator import ComputationalGraphNodeGenerator
@@ -84,7 +85,8 @@ class DirectionalOperatorGenerator(object):
     __metaclass__ = ABCMeta
     
     @debug
-    def __init__(self, operator, base_kwds, name=None, **op_kwds):
+    def __init__(self, operator, base_kwds, 
+                    name=None, pretty_name=None, **op_kwds):
         """
         Initialize a DirectionalOperatorGenerator.
 
@@ -101,14 +103,11 @@ class DirectionalOperatorGenerator(object):
             Keywords arguments that will be passed towards operator.__init__ 
             during a call to _generate. In addition to those arguments, 
             direction and splitting_dim will also be passed.
-            If name is present in op_kwds, generated names will be 
-                op_kwds['name'] + '_' + DirectionLabels[dir]
-            else:
-                self.__class__.__name__ + '_' + DirectionLabels[dir]
         """
         super(DirectionalOperatorGenerator,self).__init__(**base_kwds)
 
-        self.name = name or type(self).__name__
+        self.name = first_not_None(name, type(self).__name__)
+        self.pretty_name = first_not_None(pretty_name, self.name)
 
         self._operator = operator
         self._op_kwds = op_kwds
@@ -174,20 +173,22 @@ class DirectionalOperatorGenerator(object):
     @generated
     def generate_direction(self, i, dt_coeff):
         kwds = self._op_kwds
-        if 'name' in kwds:
-            basename = kwds.pop('name')
-        else:
-            basename = self.name
+        basename = kwds.pop('name', self.name)
+        basepname = kwds.pop('pretty_name', self.pretty_name)
 
         kargs = {}
         kargs.update(kwds)
         kargs.update(self.custom_directional_kwds(i))
 
         name = '{}_{}_{}'.format(basename, DirectionLabels[i], self._direction_counter[i])
+        pname = u'{}_{}{}'.format(basepname, DirectionLabels[i], 
+                    subscript(self._direction_counter[i]))
+        pname = pname.encode('utf-8')
         self._direction_counter[i]+=1
 
         try:
-            op = self._operator(name=name, splitting_direction=i, dt_coeff=dt_coeff, **kargs)
+            op = self._operator(name=name, pretty_name=pname,
+                    splitting_direction=i, dt_coeff=dt_coeff, **kargs)
         except:
             sargs = ['*{} = {}'.format(k,v.__class__) 
                         for (k,v) in kargs.iteritems()]
diff --git a/hysop/operator/redistribute.py b/hysop/operator/redistribute.py
index c5846b75ed5035a78fb4dfe699947c6319048d8a..115abd3204128be14d62d76eee6dab3c8df8ceb1 100644
--- a/hysop/operator/redistribute.py
+++ b/hysop/operator/redistribute.py
@@ -40,7 +40,8 @@ class Redistribute(ComputationalGraphNodeGenerator):
                 '{} is not a RedistributeOperatorBase.'.format(cls)
 
     def __init__(self, variables, source_topos, target_topo, components=None, 
-            name=None, base_kwds=None, **kwds):
+            name=None, pretty_name=None, 
+            base_kwds=None, **kwds):
         """
         Initialize a Redistribute operator generator.
         Parameters
@@ -55,6 +56,8 @@ class Redistribute(ComputationalGraphNodeGenerator):
             which component of the fields must be distributed (default = all components)
         name: string
             prefix for generated operator names
+        pretty_name: string
+            pretty prefix for generated operator names
         base_kwds: dict, optional, defaults to None
             Base class keywords arguments.
             If None, an empty dict will be passed.
@@ -66,7 +69,7 @@ class Redistribute(ComputationalGraphNodeGenerator):
         assert 'source_topo' not in kwds
 
         base_kwds = base_kwds or dict()
-        super(Redistribute,self).__init__(name=name, **base_kwds)
+        super(Redistribute,self).__init__(name=name, pretty_name=pretty_name, **base_kwds)
 
         # format variables to a set of variables
         variables = to_set(variables)
@@ -104,7 +107,6 @@ class Redistribute(ComputationalGraphNodeGenerator):
         self._source_topos = source_topos
         self._target_topo = target_topo
         self._components = components 
-        self._name = name
         self._kwds = kwds
     
     @debug
@@ -116,17 +118,12 @@ class Redistribute(ComputationalGraphNodeGenerator):
             components   = self._components[var]
             kwds         = self._kwds.copy()
             
-            if (self._name is not None):
-                name  = self._name + '_{}'.format(var.name)
-                name += ''.join([DirectionLabels[i] for i in sorted(components)]).lower()
-                kwds['name'] = name
-        
             # if source topology is destination topology there is nothing to be done
             if target_topo in source_topos:
                 continue
                 
             # else we find the most suitable source topology
-            node = Redistribute._select_redistribute(variable=var, source_topos=source_topos, 
+            node = self._select_redistribute(variable=var, source_topos=source_topos, 
                                     target_topo=target_topo, components=components, **kwds)
             nodes.append(node)
         return nodes
diff --git a/hysop/operator/transpose.py b/hysop/operator/transpose.py
index b0a97b117a365af546208fca6f488f37278d342a..791239532e370be9758e5e0637c29b5a580e7928 100644
--- a/hysop/operator/transpose.py
+++ b/hysop/operator/transpose.py
@@ -43,7 +43,7 @@ class Transpose(ComputationalGraphNodeGenerator):
         from hysop.backend.host.python.operator.transpose   import PythonTranspose
         from hysop.backend.device.opencl.operator.transpose import OpenClTranspose
         _implementations = {
-                Implementation.PYTHON:         PythonTranspose,
+                Implementation.PYTHON: PythonTranspose,
                 Implementation.OPENCL: OpenClTranspose
         }
         return _implementations
@@ -303,10 +303,15 @@ class Transpose(ComputationalGraphNodeGenerator):
             TransposeOp = self._get_op_and_check_implementation(src_topo, dst_topo)
             axes = TransposeOp.get_preferred_axes(src_topo, dst_topo, self.candidate_axes)
 
-            if (self.name is not None):
-                name  = self.name + '_{}_'.format(ifield.name)
-                name += ''.join([DirectionLabels[i] for i in axes]).lower()
-                kwds['name'] = name
+            name = self.name.replace('Transpose', 'T')
+            name  = self.name + '_{}_'.format(ifield.name)
+            name += ''.join([DirectionLabels[i] for i in axes]).lower()
+            kwds['name'] = name
+            
+            pretty_name = self.pretty_name.replace('Transpose', 'T')
+            pname  = pretty_name + u'{}_'.format(ifield.pretty_name.decode('utf-8'))
+            pname += u''.join([DirectionLabels[i] for i in axes]).lower()
+            kwds['pretty_name'] = pname.encode('utf-8')
 
             variables = { ifield: src_topo }
             variables[ofield] = dst_topo
diff --git a/hysop/tools/handle.py b/hysop/tools/handle.py
index 8927ec30662737e816c3054271cd296e26db9a2e..4806c367e11ce19bed4d3146c804427558044ccd 100644
--- a/hysop/tools/handle.py
+++ b/hysop/tools/handle.py
@@ -3,6 +3,7 @@ from abc import ABCMeta, abstractmethod
 from hysop.deps import np
 from hysop.tools.decorators import not_implemented, debug
 from hysop.tools.types import to_tuple, first_not_None
+from hysop.tools.sympy_utils import subscript
 from hysop.core.mpi import MPI
 
 class TaggedObjectView(object):
@@ -39,12 +40,20 @@ class TaggedObjectView(object):
         else:
             return getattr(self.__obj_view, '_TaggedObject__get_object_tag')()
     
+    def __get_object_pretty_tag(self):
+        """Unique pretty tag of the underlying object view."""
+        if (not hasattr(self, '_TaggedObjectView__obj_view')) or (self.__obj_view is None):
+            assert isinstance(self, TaggedObject)
+            return getattr(self, '_TaggedObject__get_object_pretty_tag')()
+        else:
+            return getattr(self.__obj_view, '_TaggedObject__get_object_pretty_tag')()
     def __get_object_full_tag(self):
         """Unique tag of the underlying object view with cls information."""
         return '{}::{}'.format(self.__class__.__name__, self.__get_object_tag())
 
     id  = property(__get_object_id)
     tag = property(__get_object_tag)
+    pretty_tag = property(__get_object_pretty_tag)
     full_tag = property(__get_object_full_tag)
 
     @abstractmethod
@@ -129,6 +138,16 @@ class TaggedObject(object):
                 self.__tag_formatter(self.__tag_id), 
                 self.__tag_postfix)
     
+    def __get_object_pretty_tag(self):
+        """
+        Get the formatted pretty tag of this object as a string.
+        This is an instance identifier 
+        """
+        return u'{}{}{}'.format(
+                self.__tag_prefix, 
+                self.__tag_formatter(subscript(self.__tag_id)), 
+                self.__tag_postfix).encode('utf-8')
+    
     def __get_object_full_tag(self):
         """
         Get the formatted tag of this object as a string.
@@ -139,6 +158,7 @@ class TaggedObject(object):
 
     id  = property(__get_object_id)
     tag = property(__get_object_tag)
+    pretty_tag = property(__get_object_pretty_tag)
     full_tag = property(__get_object_full_tag)
      
     @abstractmethod
diff --git a/hysop/tools/string_utils.py b/hysop/tools/string_utils.py
index 4e6bb1e3fca89794cb328ca651677c73faafa367..9e1a87957f71616a5e98052413e0917a2872496b 100644
--- a/hysop/tools/string_utils.py
+++ b/hysop/tools/string_utils.py
@@ -47,4 +47,9 @@ def framed_str(title, msg, c='=', at_border=2):
     title  = c*at_border + title + c*at_border
     header = title + c*max(0, length-len(title))
     footer = c*len(header)
-    return '{}\n{}\n{}'.format(header, msg, footer)
+    return u'{}\n{}\n{}'.format(header, msg, footer)
+
+def strlen(s):
+    """Like length but replace unicode characters by space before applying len()"""
+    #res = len(s.decode('utf-8'))
+    return len(s)