Index: /codes/icosagcm/devel/Python/src/unstructured/macros.jin
===================================================================
--- /codes/icosagcm/devel/Python/src/unstructured/macros.jin	(revision 643)
+++ /codes/icosagcm/devel/Python/src/unstructured/macros.jin	(revision 644)
@@ -14,10 +14,10 @@
 #define FORALL_CELLS(...) {% call(lrange,flags) forall_cells(__VA_ARGS__) %}
 #define FORALL_CELLS_EXT(...) {% call(lrange,flags) forall_cells(__VA_ARGS__) %}
-#define ON_PRIMAL {% call(mesh,lrange) on_mesh('primal',lrange,flags) %}
-#define ON_DUAL {% call(mesh,lrange) on_mesh('dual',lrange,flags) %}
-#define ON_EDGES {% call(mesh,lrange) on_edges('edge',lrange,flags) %}
-#define FORALL_EDGES {% call forall_edges(mesh) %}
-#define FORALL_VERTICES {% call forall_vertices(mesh) %}
-#define FORALL_TRISK {% call forall_trisk() %}
+#define ON_PRIMAL {% call(mesh, degree=0) on_mesh('primal',lrange,flags) %}
+#define ON_DUAL {% call(mesh, degree=0) on_mesh('dual',lrange,flags) %}
+#define ON_EDGES {% call(mesh, degree=0) on_edges('edge',lrange,flags) %}
+#define FORALL_EDGES {% call forall_edges(mesh,degree) %}
+#define FORALL_VERTICES {% call forall_vertices(mesh,degree) %}
+#define FORALL_TRISK {% call forall_trisk(degree) %}
 #define END_BLOCK {% endcall %}
 #define SEQUENCE {% call sequence() %} 
@@ -39,4 +39,11 @@
 {#  -------------------------- Design notes ------------------------------
 
+The syntax 
+{% call(ARGNAMES) macro(ARGS) %}
+...
+{% endcall %}
+passes ARGS to macro ; this macro "calls" the body using the syntax 'caller(arg1,...)' ; these arguments
+are available in the body under the names ARGNAMES, as if it were a macro caller(ARGNAMES).
+
 Using its optional argument 'options', forall_cells() sets variable 'flags' 
 and passes it on to on_mesh() / on_edges()
@@ -45,4 +52,5 @@
 
 -------------------------------------------------------------------------- #}
+
 
 {# ----------------------- SEQUENCE, FORALL ----------------------- #}
@@ -80,7 +88,68 @@
 {# ------------------------------ MESHES --------------------------- #}
 
-{% macro vloop(mesh, lrange, flags, code) %}
+{# argument 'code' is the body enclosed by ON_XXX ... END_BLOCK ; it takes arguments : mesh,degree=0 #}
+
+{% macro vloop_unroll(mesh, lrange, flags, code) %}
+
+{% set thecode, has_primal, has_dual, has_trisk, has_none = code(mesh), False, False, False, True %}
+
+{% if 'primal_deg' in thecode %}
+! this VLOOP iterates over primal cell edges
+{% set has_primal, has_none = True,False %}
+{% endif %}
+{% if 'dual_deg' in thecode %}
+! this VLOOP iterates over dual cell edges
+{% set has_dual,has_none = True,False %}
+{% endif %}
+{% if 'trisk_deg' in thecode %}
+! this VLOOP iterates over the TRISK stencil
+{% set has_trisk,has_none = True,False %}
+{% endif %}
+
+{% if has_none %}
+{{ vloop(mesh, lrange, flags, code) }}
+{% endif %}
+
+{% if has_primal %}
+SELECT CASE(primal_deg(ij))
+CASE(4)
+{{ vloop(mesh, lrange, flags, code, 4) }}
+CASE(5)
+{{ vloop(mesh, lrange, flags, code, 5) }}
+CASE(6)
+{{ vloop(mesh, lrange, flags, code, 6) }}
+CASE DEFAULT
+{{ vloop(mesh, lrange, flags, code) }}
+END SELECT
+{% endif %}
+
+{% if has_dual %}
+SELECT CASE(dual_deg(ij))
+CASE(3)
+{{ vloop(mesh, lrange, flags, code, 3) }}
+CASE(4)
+{{ vloop(mesh, lrange, flags, code, 4) }}
+CASE DEFAULT
+{{ vloop(mesh, lrange, flags, code) }}
+END SELECT
+{% endif %}
+
+{% if has_trisk %}
+SELECT CASE(trisk_deg(edge))
+CASE(10)
+{{ vloop(mesh, lrange, flags, code, 10) }}
+CASE(4)
+{{ vloop(mesh, lrange, flags, code, 4) }}
+CASE DEFAULT
+{{ vloop(mesh, lrange, flags, code) }}
+END SELECT
+{% endif %}
+
+{%- endmacro %}
+
+{% macro vloop(mesh, lrange, flags, code, degree=0) %}
+
 {% set start,end = lrange %}
-{% set thecode, is_top_layer, is_top_inter = code(mesh), False, False %}
+{% set thecode, is_top_layer, is_top_inter = code(mesh,degree), False, False %}
 
 {{ define('IS_TOP_LAYER', '_FALSE_') }}
@@ -140,5 +209,5 @@
 !$OMP DO SCHEDULE(STATIC)                                                                            
 DO ij = 1, {{ mesh }}_num
-{{ vloop(mesh, lrange, flags, caller) }}
+{{ vloop_unroll(mesh, lrange, flags, caller) }}
 END DO
 !$OMP END DO
@@ -164,5 +233,5 @@
 {{ 'ij_up = up(edge)'       if 'VERTEX1' in thecode }}
 {{ 'ij_down = down(edge)'   if 'VERTEX2' in thecode }}
-{{ vloop(mesh, lrange, flags, caller) }}
+{{ vloop_unroll(mesh, lrange, flags, caller) }}
 END DO
 !$OMP END DO
@@ -176,5 +245,5 @@
 {%- endmacro %}
 
-{% macro forall_edges(mesh) -%}
+{% macro forall_edges(mesh,degree) -%}
 {% set thecode = caller() %}
 {{ define('EDGE', 'l,edge') }}
@@ -183,10 +252,22 @@
 {{ define('SIGN', mesh + '_ne(iedge,ij)') }}
 {{ define('LE_DE', 'le_de(edge)') }}
+
+{% if degree>1 %}
+{% for iedge in range(1,degree+1) %}
+  iedge = {{ iedge }}
+  edge = {{ mesh }}_edge({{ iedge }},ij)
+  {{ 'ij_up = up(edge)'       if 'VERTEX1' in thecode }}
+  {{ 'ij_down = down(edge)'   if 'VERTEX2' in thecode }}
+  {{ thecode }}
+{% endfor %}
+{% else %}
 DO iedge = 1, {{ mesh }}_deg(ij)
   edge = {{ mesh }}_edge(iedge,ij)
-{{ 'ij_up = up(edge)'       if 'VERTEX1' in thecode }}
-{{ 'ij_down = down(edge)'   if 'VERTEX2' in thecode }}
-  {{ thecode }}
-END DO
+  {{ 'ij_up = up(edge)'       if 'VERTEX1' in thecode }}
+  {{ 'ij_down = down(edge)'   if 'VERTEX2' in thecode }}
+  {{ thecode }}
+END DO
+{% endif %}
+
 {{ undef('EDGE') }}
 {{ undef('SIGN') }}
@@ -194,19 +275,36 @@
 {%- endmacro %}
 
-{% macro forall_trisk() -%}
+{% macro forall_trisk(degree) -%}
+{% set thecode = caller() %}
 {{ define('EDGE_TRISK', 'l,edge_trisk') }}
+{% if degree>1 %}
+{% for itrisk in range(1,degree+1) %}
+  edge_trisk = trisk({{ itrisk }},edge)
+  {{ thecode }}
+{% endfor %}
+{% else %}
 DO itrisk = 1, trisk_deg(edge)
   edge_trisk = trisk(itrisk,edge)
-  {{ caller() }}
-END DO
+  {{ thecode }}
+END DO
+{% endif %}
 {{ undef('EDGE_TRISK') }}
 {%- endmacro %}
 
-{% macro forall_vertices(mesh) -%}
+{% macro forall_vertices(mesh,degree) -%}
+{% set thecode = caller() %}
 {{ define('VERTEX', 'l,vertex') }}
+{% if degree>1 %}
+{% for ivertex in range(1,degree+1) %}
+  ivertex = {{ ivertex }}
+  vertex = {{ mesh }}_vertex({{ ivertex }},ij) 
+  {{ thecode }}
+{% endfor %}
+{% else %}
 DO ivertex = 1, {{ mesh }}_deg(ij)
   vertex = {{ mesh }}_vertex(ivertex,ij)
-  {{ caller() }}
-END DO
+  {{ thecode }}
+END DO
+{% endif %}
 {{ undef('VERTEX') }}
 {%- endmacro %}
