From 99e845d2d05c3407aa70575fb0ab9942b0cc550f Mon Sep 17 00:00:00 2001 From: Josh Davies Date: Tue, 20 Jan 2026 11:58:08 +0000 Subject: [PATCH 1/4] fix(grcc): suppress MesPrint's extra linebreak in grcc_fprintf Rely on the linebreaks provided in the strings. --- sources/grcc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/grcc.cc b/sources/grcc.cc index 4d7669a3..470462ec 100644 --- a/sources/grcc.cc +++ b/sources/grcc.cc @@ -10590,7 +10590,7 @@ static void grcc_fprintf(FILE* out, const char* fmt, ...) char *buffer = new char[len+1]; vsnprintf(buffer, len+1, fmt, args_copy); MLOCK(ErrorMessageLock); - MesPrint("%s", buffer); + MesPrint("%s%", buffer); MUNLOCK(ErrorMessageLock); delete[] buffer; va_end(args_copy); From 0de00c0e28852198c83f219be265c3b872b2dc3c Mon Sep 17 00:00:00 2001 From: Josh Davies Date: Tue, 20 Jan 2026 12:32:59 +0000 Subject: [PATCH 2/4] feat(grcc): allow the user to enable verbose printing from grcc Useful to get extra information on why a model or diagrams_ call is invalid, for example. --- doc/manual/statements.tex | 8 ++++++++ sources/compcomm.c | 1 + sources/diawrap.cc | 2 +- sources/grcc.cc | 1 + sources/structs.h | 1 + 5 files changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/manual/statements.tex b/doc/manual/statements.tex index 1febcfec..af47f98e 100644 --- a/doc/manual/statements.tex +++ b/doc/manual/statements.tex @@ -3833,6 +3833,10 @@ \section{off} \leftvitem{3.5cm}{flint\index{off!flint}} \rightvitem{13cm}{Disables the interface to FLINT; use FORM's built-in polynomial routines.} + +\leftvitem{3.5cm}{grccverbose\index{off!grccverbose}} +\rightvitem{13cm}{Disables extra print statements from the diagram generator. +This is the default.} \leftvitem{3.5cm}{highfirst\index{off!highfirst}} \rightvitem{13cm}{Puts the sorting in a low first mode.} @@ -4038,6 +4042,10 @@ \section{on} and when using Modulus\index{modulus} (\ref{substamodulus}) mode. Note that occasionally the overall sign of gcd\_ may differ from that of the built-in routine.} + +\leftvitem{3.5cm}{grccverbose\index{on!grccverbose}} +\rightvitem{13cm}{Enable extra print statements from the diagram generator. +Useful for debugging error messages. Default is off.} \leftvitem{3.5cm}{highfirst\index{on!highfirst}} \rightvitem{13cm}{In this mode polynomials are sorted in a way that high diff --git a/sources/compcomm.c b/sources/compcomm.c index ecf07f0b..da4b8a34 100644 --- a/sources/compcomm.c +++ b/sources/compcomm.c @@ -142,6 +142,7 @@ static KEYWORDV onoffoptions[] = { ,{"flint", &(AC.FlintPolyFlag), 1, 0} ,{"humanstats", &(AC.HumanStatsFlag), 1, 0} ,{"humanstatistics", &(AC.HumanStatsFlag), 1, 0} + ,{"grccverbose", &(AC.GrccVerbose), 1, 0} }; static WORD one = 1; diff --git a/sources/diawrap.cc b/sources/diawrap.cc index c2153ef3..de604253 100644 --- a/sources/diawrap.cc +++ b/sources/diawrap.cc @@ -809,7 +809,7 @@ int GenDiagrams(PHEAD WORD *term, WORD level) Options *opt; Process *proc; int pid = 1, x; - int babble = 0; // Later we may set this at the FORM code level + int babble = AC.GrccVerbose ? 2 : 0; TERMINFO info; WORD inset,outset,*coupl,setnum,optionnumber = 0; int i, j, cpl[GRCC_MAXNCPLG]; diff --git a/sources/grcc.cc b/sources/grcc.cc index 470462ec..d8ec1b8d 100644 --- a/sources/grcc.cc +++ b/sources/grcc.cc @@ -2324,6 +2324,7 @@ void Model::addInteraction(IInput *iinp) grcc_fprintf(GRCC_Stderr, "*** illegal coupling const : "); grcc_fprintf(GRCC_Stderr, "nlegs - 2 + 2*loop: 2*loop = %d\n", lp2); } + erEnd("illegal value of c-constants"); } lp = lp2/2; diff --git a/sources/structs.h b/sources/structs.h index 1c28fd2a..651a6ddf 100644 --- a/sources/structs.h +++ b/sources/structs.h @@ -1825,6 +1825,7 @@ struct C_const { int PrintBacktraceFlag; /* Print backtrace on terminate? */ int FlintPolyFlag; /* Use Flint for polynomial arithmetic */ int HumanStatsFlag; /* Print human-readable stats in the stats print? */ + int GrccVerbose; /* Enable extra print statements in grcc? */ int doloopstacksize; int dolooplevel; int CheckpointFlag; /**< Tells preprocessor whether checkpoint code must executed. From e16d6e1f44caca2c0d71d4f612d926ff6db5cf92 Mon Sep 17 00:00:00 2001 From: Josh Davies Date: Tue, 20 Jan 2026 14:22:11 +0000 Subject: [PATCH 3/4] fix(grcc): do not allow negative vectors in sets for diagrams_ --- check/features.frm | 22 ++++++++++++++++++++++ sources/diawrap.cc | 32 +++++++++++++++++++++++++++----- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/check/features.frm b/check/features.frm index a22e1cfd..0a4dbdb2 100644 --- a/check/features.frm +++ b/check/features.frm @@ -3101,3 +3101,25 @@ Local test = diagrams_(PHI3,{phi},{phi},{q1,q2},{},1,0); #pend_if mpi? assert runtime_error?('Insufficient internal momenta in diagrams_') *--#] diagrams_err_4 : +*--#[ diagrams_err_5 : +Vector q1,q2,p1,p2; +Model PHI3; + Particle phi,1; + Vertex phi,phi,phi:g; +EndModel; +Local test = diagrams_(PHI3,{phi},{phi},{q1,-q2},{p1,p2},1,0); +.end +#pend_if mpi? +assert runtime_error?('Invalid negative external momentum in diagrams_: -q2') +*--#] diagrams_err_5 : +*--#[ diagrams_err_6 : +Vector q1,q2,p1,p2; +Model PHI3; + Particle phi,1; + Vertex phi,phi,phi:g; +EndModel; +Local test = diagrams_(PHI3,{phi},{phi},{q1,q2},{-p1,p2},1,0); +.end +#pend_if mpi? +assert runtime_error?('Invalid negative internal momentum in diagrams_: -p1') +*--#] diagrams_err_6 : diff --git a/sources/diawrap.cc b/sources/diawrap.cc index de604253..7fc52fe8 100644 --- a/sources/diawrap.cc +++ b/sources/diawrap.cc @@ -894,6 +894,14 @@ int GenDiagrams(PHEAD WORD *term, WORD level) info.legcouple[i+ninitl] = m->vertices[numParticle(m,x)]->couplings; } info.numextern = ninitl + nfinal; + for ( i = 2; i <= MAXLEGS; i++ ) { + if ( m->legcouple[i] == 1 ) { + for ( j = 0; j < info.numextern; j++ ) { + if ( info.legcouple[j][i] == 0 ) { info.flags |= CHECKEXTERN; goto Go_on; } + } + } + } + // Check that we have sufficient external momenta in the set: if ( info.numextern > Sets[info.externalset].last - Sets[info.externalset].first ) { MLOCK(ErrorMessageLock); @@ -901,13 +909,27 @@ int GenDiagrams(PHEAD WORD *term, WORD level) MUNLOCK(ErrorMessageLock); Terminate(-1); } - for ( i = 2; i <= MAXLEGS; i++ ) { - if ( m->legcouple[i] == 1 ) { - for ( j = 0; j < info.numextern; j++ ) { - if ( info.legcouple[j][i] == 0 ) { info.flags |= CHECKEXTERN; goto Go_on; } - } + + // Check that none of the supplied momenta are negative: + for ( i = 0; i < Sets[info.externalset].last - Sets[info.externalset].first; i++ ) { + if ( SetElements[Sets[info.externalset].first + i] < AM.OffsetVector ) { + MLOCK(ErrorMessageLock); + MesPrint("&Invalid negative external momentum in diagrams_: -%s", + VARNAME(vectors,SetElements[Sets[info.externalset].first + i]+WILDMASK-AM.OffsetVector)); + MUNLOCK(ErrorMessageLock); + Terminate(-1); } } + for ( i = 0; i < Sets[info.internalset].last - Sets[info.internalset].first; i++ ) { + if ( SetElements[Sets[info.internalset].first + i] < AM.OffsetVector ) { + MLOCK(ErrorMessageLock); + MesPrint("&Invalid negative internal momentum in diagrams_: -%s", + VARNAME(vectors,SetElements[Sets[info.internalset].first + i]+WILDMASK-AM.OffsetVector)); + MUNLOCK(ErrorMessageLock); + Terminate(-1); + } + } + Go_on:; // // Now we have to sort out the coupling constants. From ebe385f86273139366418b38aa43da04ff6aa546 Mon Sep 17 00:00:00 2001 From: Josh Davies Date: Tue, 20 Jan 2026 14:44:54 +0000 Subject: [PATCH 4/4] fix(grcc): do not allow repeated vectors in sets for diagrams_ --- check/features.frm | 22 ++++++++++++++++++++++ sources/diawrap.cc | 30 +++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/check/features.frm b/check/features.frm index 0a4dbdb2..0e53f0fa 100644 --- a/check/features.frm +++ b/check/features.frm @@ -3123,3 +3123,25 @@ Local test = diagrams_(PHI3,{phi},{phi},{q1,q2},{-p1,p2},1,0); #pend_if mpi? assert runtime_error?('Invalid negative internal momentum in diagrams_: -p1') *--#] diagrams_err_6 : +*--#[ diagrams_err_7 : +Vector q1,q2,p1,p2; +Model PHI3; + Particle phi,1; + Vertex phi,phi,phi:g; +EndModel; +Local test = diagrams_(PHI3,{phi},{phi},{q1,q1},{p1,p2},1,0); +.end +#pend_if mpi? +assert runtime_error?('Invalid repeated momentum in diagrams_: q1') +*--#] diagrams_err_7 : +*--#[ diagrams_err_8 : +Vector q1,q2,p1,p2; +Model PHI3; + Particle phi,1; + Vertex phi,phi,phi:g; +EndModel; +Local test = diagrams_(PHI3,{phi},{phi},{q1,q2},{q1,p2},1,0); +.end +#pend_if mpi? +assert runtime_error?('Invalid repeated momentum in diagrams_: q1') +*--#] diagrams_err_8 : diff --git a/sources/diawrap.cc b/sources/diawrap.cc index 7fc52fe8..7cc917d6 100644 --- a/sources/diawrap.cc +++ b/sources/diawrap.cc @@ -36,6 +36,7 @@ extern "C" { #include "grccparam.h" #include "grcc.h" +#include #define MAXPOINTS 120 @@ -815,6 +816,7 @@ int GenDiagrams(PHEAD WORD *term, WORD level) int i, j, cpl[GRCC_MAXNCPLG]; int ninitl, initlPart[GRCC_MAXLEGS], nfinal, finalPart[GRCC_MAXLEGS]; for ( i = 0; i < GRCC_MAXNCPLG; i++ ) cpl[i] = 0; + std::map momlist; // // Here we create an object of type Option and load it up. // Next we run the diagram generation on it. @@ -910,21 +912,39 @@ int GenDiagrams(PHEAD WORD *term, WORD level) Terminate(-1); } - // Check that none of the supplied momenta are negative: + // Check that none of the supplied momenta are negative or repeated: for ( i = 0; i < Sets[info.externalset].last - Sets[info.externalset].first; i++ ) { - if ( SetElements[Sets[info.externalset].first + i] < AM.OffsetVector ) { + const int momcode = SetElements[Sets[info.externalset].first + i]; + if ( momcode < AM.OffsetVector ) { MLOCK(ErrorMessageLock); MesPrint("&Invalid negative external momentum in diagrams_: -%s", - VARNAME(vectors,SetElements[Sets[info.externalset].first + i]+WILDMASK-AM.OffsetVector)); + VARNAME(vectors, momcode+WILDMASK-AM.OffsetVector)); + MUNLOCK(ErrorMessageLock); + Terminate(-1); + } + momlist[momcode]++; + if ( momlist[momcode] != 1 ) { + MLOCK(ErrorMessageLock); + MesPrint("&Invalid repeated momentum in diagrams_: %s", + VARNAME(vectors, momcode-AM.OffsetVector)); MUNLOCK(ErrorMessageLock); Terminate(-1); } } for ( i = 0; i < Sets[info.internalset].last - Sets[info.internalset].first; i++ ) { - if ( SetElements[Sets[info.internalset].first + i] < AM.OffsetVector ) { + const int momcode = SetElements[Sets[info.internalset].first + i]; + if ( momcode < AM.OffsetVector ) { MLOCK(ErrorMessageLock); MesPrint("&Invalid negative internal momentum in diagrams_: -%s", - VARNAME(vectors,SetElements[Sets[info.internalset].first + i]+WILDMASK-AM.OffsetVector)); + VARNAME(vectors, momcode+WILDMASK-AM.OffsetVector)); + MUNLOCK(ErrorMessageLock); + Terminate(-1); + } + momlist[momcode]++; + if ( momlist[momcode] != 1 ) { + MLOCK(ErrorMessageLock); + MesPrint("&Invalid repeated momentum in diagrams_: %s", + VARNAME(vectors, momcode-AM.OffsetVector)); MUNLOCK(ErrorMessageLock); Terminate(-1); }