• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vermaseren / form / 9364948935

04 Jun 2024 09:49AM UTC coverage: 49.979% (-0.02%) from 49.999%
9364948935

Pull #526

github

web-flow
Merge 7062bd769 into 83e3d4185
Pull Request #526: RFC: better debugging

52 of 415 new or added lines in 46 files covered. (12.53%)

32 existing lines in 2 files now uncovered.

41391 of 82816 relevant lines covered (49.98%)

878690.77 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

31.31
/sources/diawrap.cc
1
//        #[ Includes : diawrap.cc
2

3
extern "C" {
4
#include "form3.h"
5
}
6

7
#include "grccparam.h"
8
#include "grcc.h"
9
 
10
#define MAXPOINTS 120
11

12
typedef struct ToPoTyPe {
13
        WORD *vert;
14
        WORD *vertmax;
15
        Options *opt;
16
        int cldeg[MAXPOINTS], clnum[MAXPOINTS], clext[MAXPOINTS];
17
        int cmind[MAXLEGS+1],cmaxd[MAXLEGS+1];
18
        int ncl, nvert;
19
} TOPOTYPE;
20

21
static void ProcessDiagram(EGraph *eg, void *ti);
22
static int processVertex(TOPOTYPE *TopoInf, int pointsremaining, int level);
23

24
//        #] Includes : 
25
//        #[ LoadModel :
26

27
int LoadModel(MODEL *m)
11✔
28
{
29
//
30
//        First check whether there was a model already.
31
//        In the Kaneko setup there can be only one at the same time.
32
//        Hence if there was one we need to remove it first.
33
//        Unless of course, it was already the model we want.
34
//
35
        if ( m->grccmodel != NULL ) return(0);
11✔
36

37
        int i,j,k;
7✔
38
//
39
//        First the information that goes into the Model struct.
40
//        Note that new Model takes over (does not copy) minp.cnamlist.
41
//
42
        MInput minp;
7✔
43
        PInput pinp;
7✔
44
        IInput iinp;
7✔
45
        if ( m->ncouplings > GRCC_MAXNCPLG ) {
7✔
46
                MesPrint("Too many coupling constants in model. Current limit is %d.",(WORD)GRCC_MAXNCPLG);
×
47
                MesPrint("Suggestion: recompile Form with a larger value for GRCC_MAXNCPLG");
×
48
                return(-1);
×
49
        }
50
        minp.defpart = GRCC_DEFBYCODE;
7✔
51
        minp.name = (char *)(m->name);
7✔
52
        minp.ncouple = m->ncouplings;
7✔
53
        for ( i = 0; i < GRCC_MAXNCPLG; i++ ) minp.cnamlist[i] = NULL;
35✔
54
        for ( i = 0; i < minp.ncouple; i++ )
14✔
55
                minp.cnamlist[i] = (char *)(VARNAME(symbols,m->couplings[i]));
7✔
56
        Model *mdl = new Model(&minp);
7✔
57
//
58
//        Now the particles
59
//
60
        for ( i = 0; i < m->nparticles; i++ ) {
14✔
61
                if ( minp.defpart == GRCC_DEFBYCODE ) {
7✔
62
                        pinp.name = NULL;
7✔
63
                        pinp.aname = NULL;
7✔
64
                        pinp.pcode = m->vertices[i]->particles[0].number;
7✔
65
                        pinp.acode = m->vertices[i]->particles[1].number;
7✔
66
                        switch ( m->vertices[i]->particles[0].spin ) {
7✔
67
                          case 1:
7✔
68
                                pinp.ptypec = GRCC_PT_Scalar;
7✔
69
                          break;
7✔
70
                          case -1:
×
71
                                pinp.ptypec = GRCC_PT_Ghost;
×
72
                          break;
×
73
                          case 2:
×
74
                                if ( m->vertices[i]->particles[0].type == 0 )
×
75
                                        pinp.ptypec = GRCC_PT_Majorana;
×
76
                                else
77
                                        pinp.ptypec = GRCC_PT_Undef;
×
78
                          break;
79
                          case -2:
×
80
                                if ( m->vertices[i]->particles[0].type == 0 )
×
81
                                        pinp.ptypec = GRCC_PT_Majorana;
×
82
                                else
83
                                        pinp.ptypec = GRCC_PT_Dirac;
×
84
                          break;
85
                          case 3:
×
86
                                pinp.ptypec = GRCC_PT_Vector;
×
87
                          break;
×
88
                          default:
×
89
                                pinp.ptypec = GRCC_PT_Undef;
×
90
                          break;
×
91
                        }
92
                }
93
                else {
94
                        pinp.name   = (char *)(VARNAME(functions,m->vertices[i]->particles[0].number));
×
95
                        pinp.aname  = (char *)(VARNAME(functions,m->vertices[i]->particles[1].number));
×
96
                        switch ( m->vertices[i]->particles[0].spin ) {
×
97
                          case 1:
×
98
                                pinp.ptypen = "scalar";
×
99
                          break;
×
100
                          case -1:
×
101
                                pinp.ptypen = "ghost";
×
102
                          break;
×
103
                          case 2:
×
104
                                if ( m->vertices[i]->particles[0].type == 0 )
×
105
                                        pinp.ptypen = "majorana";
×
106
                                else
107
                                        pinp.ptypen = "undef";
×
108
                          break;
109
                          case -2:
×
110
                                if ( m->vertices[i]->particles[0].type == 0 )
×
111
                                        pinp.ptypen = "majorana";
×
112
                                else
113
                                        pinp.ptypen = "dirac";
×
114
                          break;
115
                          case 3:
×
116
                                pinp.ptypen = "vector";
×
117
                          break;
×
118
                          default:
×
119
                                pinp.ptypen = "undef";
×
120
                          break;
×
121
                        }
122
                }
123
                pinp.extonly = m->vertices[i]->externonly;
7✔
124
                mdl->addParticle(&pinp);
7✔
125
        }
126
        mdl->addParticleEnd();
7✔
127
//
128
//        Now the vertices
129
//
130
        for ( i = m->nparticles; i < m->invertices; i++ ) {
14✔
131
                VERTEX *v = m->vertices[i];
7✔
132
                if ( minp.defpart == GRCC_DEFBYCODE ) {
7✔
133
                        iinp.icode = NODEFUNCTION+i;
7✔
134
                        iinp.name = NULL;
7✔
135
                }
136
                else {
137
                        iinp.name = "node_";
×
138
                }
139
                iinp.nplistn = v->nparticles;
7✔
140
                for ( j = 0; j < iinp.nplistn; j++ ) {
28✔
141
                        if ( minp.defpart == GRCC_DEFBYCODE ) {
21✔
142
                                iinp.plistc[j] = v->particles[j].number;
21✔
143
                        }
144
                        else {
145
                                iinp.plistn[j] = (char *)(VARNAME(functions,v->particles[j].number));
×
146
                        }
147
                }
148
//
149
//                We need a properly ordered list of coupling constants
150
//                The ordered list is in m->couplings.
151
//                For each vertex they are in v->couplings.
152
//
153
//                iinp.cvallist = (int *)Malloc1(m->ncouplings*sizeof(int),"couplings");
154

155
                for ( j = 0; j < m->ncouplings; j++ ) {
14✔
156
                        iinp.cvallist[j] = 0;
7✔
157
                        for ( k = 0; k < v->ncouplings; k += 2 ) {
7✔
158
                                if ( v->couplings[k] == m->couplings[j] ) {
7✔
159
                                        iinp.cvallist[j] = v->couplings[k+1];
7✔
160
                                        break;
7✔
161
                                }
162
                        }
163
                }
164
                mdl->addInteraction(&iinp);
7✔
165
        }
166
        mdl->addInteractionEnd();
7✔
167
        m->grccmodel = (void *)mdl;
7✔
168
        return(0);
7✔
169
}
170

171
//        #] LoadModel : 
172
//        #[ ConvertParticle :
173

174
int ConvertParticle(Model *model,int formnum)
8✔
175
{
176
//
177
//  Returns the grcc number of the particle, because grcc does not convert
178
//
179
    int i;
8✔
180
    for ( i = 0; i < model->nParticles; i++ ) {
16✔
181
        if ( model->particles[i]->pcode == formnum ) { return(i); }
16✔
182
        else if ( model->particles[i]->acode == formnum ) { return(-i); }
8✔
183
    }
184
    MesPrint("Particle %d not found in model %s",formnum,model->name);
×
NEW
185
    TERMINATE(-1);
×
186
    return(0);
×
187
}
188

189
//        #] ConvertParticle : 
190
//        #[ ReConvertParticle :
191

192
int ReConvertParticle(Model *model,int grccnum)
×
193
{
194
//
195
//  Returns the grcc number of the particle, because grcc does not convert
196
//
197
        if ( grccnum < 0 ) { return(model->particles[-grccnum]->acode); }
×
198
        else { return(model->particles[grccnum]->pcode); }
×
199
}
200

201
//        #] ReConvertParticle : 
202
//        #[ numParticle :
203

204
int numParticle(MODEL *m,WORD n)
8✔
205
{
206
        int i;
8✔
207
        for ( i = 0; i < m->nparticles; i++ ) {
8✔
208
                if ( m->vertices[i]->particles[0].number == n ) return(i);
8✔
209
                if ( m->vertices[i]->particles[1].number == n ) return(i);
×
210
        }
211
        MesPrint("numParticle: particle %d not found in model",n);
×
NEW
212
        TERMINATE(-1);
×
213
        return(-1);
×
214
}
215

216
//        #] numParticle : 
217
//        #[ ProcessDiagram :
218

219
void ProcessDiagram(EGraph *eg, void *ti)
×
220
{
221
//
222
//        This is the routine that gets a complete diagram and passes it on
223
//        to Form (Generator) for further algebraic manipulations.
224
//        The term is picked up from AT.diaterm and a new term is constructed
225
//        in the workspace.
226
//
227
        GETIDENTITY
228
        TERMINFO *info = (TERMINFO *)ti;
×
229

230
        if ( ( info->flags & TOPOLOGIESONLY ) == TOPOLOGIESONLY ) return;
×
231

232
        WORD *term = info->term, *newterm, *oldworkpointer = AT.WorkPointer;
×
233
        WORD *tdia = term + info->diaoffset;
×
234
        WORD *tail = tdia + tdia[1];
×
235
        WORD *tend = term + *term;
×
236
        WORD *fill, *startfill, *cfill, *afill;
×
237
        int i, j, intr;
×
238
        Model *model = (Model *)info->currentModel;
×
239
        MODEL *m = (MODEL *)info->currentMODEL;
×
240
        int numlegs, vect, edge;
×
241

242
        newterm = term + *term;
×
243
        for ( i = 1; i < info->diaoffset; i++ ) newterm[i] = term[i];
×
244
        fill = newterm + info->diaoffset;
×
245
//
246
//        Now get the nodes
247
//
248
        if ( ( info->flags & NONODES ) == 0 ) {
×
249
          for ( i = 0; i < eg->nNodes; i++ ) {
×
250
//
251
//                node_(number,coupling,particle_1(momentum_1),...,particle_n(momentum_n))
252
//
253
                numlegs = eg->nodes[i]->deg;
×
254
                startfill = fill;
×
255
                *fill++ = NODEFUNCTION;
×
256
                *fill++ = 0;
×
257
                FILLFUN(fill)
×
258
                *fill++ = -SNUMBER; *fill++ = i+1;
×
259
//
260
//                Now we put the coupling constants. This is done inside the
261
//                function for when we want to work with counterterms.
262
//
263
                if ( !eg->isExternal(i) ) {
×
264
                        afill = fill; *fill++ = 0; *fill++ = 1; FILLARG(fill)
×
265
                        cfill = fill; *fill++ = 0;
×
266
                        intr = eg->nodes[i]->intrct;
×
267
                        for ( j = 0; j < model->interacts[intr]->nclist; j++ ) {
×
268
                                if ( model->interacts[intr]->clist[j] != 0 ) {
×
269
                                        *fill++ = SYMBOL; *fill++ = 4;
×
270
                                        *fill++ = m->couplings[j];
×
271
                                        *fill++ = model->interacts[intr]->clist[j];
×
272
                                }
273
                        }
274
                        *fill++ = 1; *fill++ = 1; *fill++ = 3;
×
275
                        *cfill = fill - cfill;
×
276
                        *afill = fill - afill;
×
277
                }
278
                else {
279
                        *fill++ = -SNUMBER;
×
280
                        *fill++ = 1;
×
281
                }
282
//
283
//                Now the particles and their momenta.
284
//
285
                for ( j = 0; j < numlegs; j++ ) {
×
286
                        *fill++ = ARGHEAD+FUNHEAD+6;
×
287
                        *fill++ = 0;
×
288
                        FILLARG(fill)
289
                        edge = eg->nodes[i]->edges[j];
×
290
                        vect = ABS(edge)-1;
×
291
                        *fill++ = 6+FUNHEAD;
×
292
                        int a;
×
293
                        if ( edge < 0 ) { a = ReConvertParticle(model,-eg->edges[vect]->ptcl); }
×
294
                        else {            a = ReConvertParticle(model,eg->edges[vect]->ptcl); }
×
295
                        *fill++ = a;
×
296
                        *fill++ = FUNHEAD+2;
×
297
                        FILLFUN(fill)
×
298
                        *fill++ = edge < 0 ? -MINVECTOR: -VECTOR;
×
299
                        if ( numlegs == 1 || vect < info->numextern ) { // Look up in set of external momenta
×
300
                                *fill++ = SetElements[Sets[info->externalset].first+vect];
×
301
                        }
302
                        else { // Look up in set of internal momenta set
303
                                *fill++ = SetElements[Sets[info->internalset].first+(vect-eg->nExtern)];
×
304
                        }
305
                        *fill++ = 1; *fill++ = 1; *fill++ = 3;
×
306
                }
307
                startfill[1] = fill-startfill;
×
308
          }
309
        }
310
        if ( ( info->flags & WITHEDGES ) == WITHEDGES ) {
×
311
                for ( i = 0; i < eg->nEdges; i++ ) {
×
312
                        int n1 = eg->edges[i]->nodes[0];
×
313
                        int n2 = eg->edges[i]->nodes[1];
×
314
//                        int l1 = eg->edges[i]->nlegs[0];
315
//                        int l2 = eg->edges[i]->nlegs[1];
316

317
                        startfill = fill;
×
318
                        *fill++ = EDGE;
×
319
                        *fill++ = 0;
×
320
                        FILLFUN(fill)
×
321
                        *fill++ = -SNUMBER; *fill++ = i+1; // number of the edge
×
322
//
323
                        *fill++ = ARGHEAD+FUNHEAD+6;
×
324
                        *fill++ = 0;
×
325
                        FILLARG(fill)
326
                        *fill++ = 6+FUNHEAD;
×
327
                        int a = ReConvertParticle(model,eg->edges[i]->ptcl);
×
328
                        *fill++ = a;
×
329
                        *fill++ = FUNHEAD+2;
×
330
                        FILLFUN(fill)
×
331
                                *fill++ = -VECTOR;
×
332
                        // Look up in set of internal momenta set
333
                        if ( i < info->numextern ) { // Look up in set of external momenta
×
334
                                *fill++ = SetElements[Sets[info->externalset].first+i];
×
335
                        }
336
                        else { // Look up in set of internal momenta set
337
                                *fill++ = SetElements[Sets[info->internalset].first+(i-eg->nExtern)];
×
338
                        }
339
                        *fill++ = 1; *fill++ = 1; *fill++ = 3;
×
340
//
341
                        *fill++ = -SNUMBER; *fill++ = n1+1; // number of the node from
×
342
                        *fill++ = -SNUMBER; *fill++ = n2+1; // number of the node to
×
343
                        startfill[1] = fill - startfill;
×
344
                }
345
        }
346
        if ( ( info->flags & WITHBLOCKS ) == WITHBLOCKS ) {
×
347
                for ( i = 0; i < eg->econn->nblocks; i++ ) {
×
348
                        startfill = fill;
×
349
                        *fill++ = BLOCK;
×
350
                        *fill++ = 0;
×
351
                        FILLFUN(fill);
×
352
                        *fill++ = -SNUMBER;
×
353
                        *fill++ = i+1;
×
354
                        *fill++ = -SNUMBER;
×
355
                        *fill++ = eg->econn->blocks[i].loop;
×
356
//
357
//                        Now we have to make a list of all nodes inside this block
358
//
359
                        int bnodes[GRCC_MAXNODES], k;
×
360
                        WORD *argfill = fill, *funfill;
×
361
                        *fill++ = 0; *fill++ = 0; FILLARG(fill)
×
362
                        *fill++ = 0;
×
363
                        for ( k = 0; k < GRCC_MAXNODES; k++ ) bnodes[k] = 0;
×
364
                        for ( k = 0; k < eg->econn->blocks[i].nmedges; k++ ) {
×
365
                                bnodes[eg->econn->blocks[i].edges[k][0]] = 1;
×
366
                                bnodes[eg->econn->blocks[i].edges[k][1]] = 1;
×
367
                        }
368
                        for ( k = 0; k < GRCC_MAXNODES; k++ ) {
×
369
                                if ( bnodes[k] == 0 ) continue;
×
370
//
371
//                                Now we put the node inside this argument.
372
//
373
                                funfill = fill;
×
374
                                *fill++ = NODEFUNCTION;
×
375
                                *fill++ = 0;
×
376
                                FILLFUN(fill)
×
377
                                *fill++ = -SNUMBER; *fill++ = k+1;
×
378
                                numlegs = eg->nodes[k]->deg;
×
379
                                for ( j = 0; j < numlegs; j++ ) {
×
380
                                        edge = eg->nodes[k]->edges[j];
×
381
                                        vect = ABS(edge)-1;
×
382
                                        *fill++ = -VECTOR;
×
383
                                        if ( numlegs == 1 || vect < info->numextern ) { // Look up in set of external momenta
×
384
                                                *fill++ = SetElements[Sets[info->externalset].first+vect];
×
385
                                        }
386
                                        else { // Look up in set of internal momenta set
387
                                                *fill++ = SetElements[Sets[info->internalset].first+(vect-info->numextern)];
×
388
                                        }
389
                                }
390
                                funfill[1] = fill-funfill;
×
391
                        }
392
                        *fill++ = 1; *fill++ = 1; *fill++ = 3;
×
393
                        *argfill = fill - argfill;
×
394
                        argfill[ARGHEAD] = argfill[0] - ARGHEAD;
×
395
                        startfill[1] = fill-startfill;
×
396
                }
397
        }
398
        if ( ( info->flags & WITHONEPI ) == WITHONEPI ) {
×
399
                for ( i = 0; i < eg->econn->nopic; i++ ) {
×
400
                        startfill = fill;
×
401
                        *fill++ = ONEPI;
×
402
                        *fill++ = 0;
×
403
                        FILLFUN(fill);
×
404
                        *fill++ = -SNUMBER;
×
405
                        *fill++ = i+1;
×
406
                        *fill++ = -ONEPI;
×
407
                        for ( j = 0; j < eg->econn->opics[i].nnodes; j++ ) {
×
408
                                *fill++ = -SNUMBER;
×
409
                                *fill++ = eg->econn->opics[i].nodes[j]+1;
×
410
                        }
411
                        startfill[1] = fill-startfill;
×
412
                }
413
        }
414
//
415
//        Topology counter. We have exaggerated a bit with the eye on the far future.
416
//
417
        if ( info->numtopo-1 < MAXPOSITIVE ) {
×
418
                *fill++ = TOPO; *fill++ = FUNHEAD+2; FILLFUN(fill)
×
419
                *fill++ = -SNUMBER; *fill++ = (WORD)(info->numtopo-1);
×
420
        }
421
        else if ( info->numtopo-1 < FULLMAX-1 ) {
×
422
                *fill++ = TOPO; *fill++ = FUNHEAD+ARGHEAD+4; FILLFUN(fill)
×
423
                *fill++ = ARGHEAD+4; *fill++ = 0; FILLARG(fill)
×
424
                *fill++ = 4;
×
425
                *fill++ = (WORD)((info->numtopo-1) & WORDMASK);
×
426
                *fill++ = 1; *fill++ = 3;
×
427
        }
428
        else {        // for now: science fiction
429
                *fill++ = TOPO; *fill++ = FUNHEAD+ARGHEAD+6; FILLFUN(fill)
×
430
                *fill++ = ARGHEAD+6; *fill++ = 0; FILLARG(fill)
×
431
                *fill++ = 6; *fill++ = (WORD)((info->numtopo-1) >> BITSINWORD);
×
432
                *fill++ = (WORD)((info->numtopo-1) & WORDMASK);
×
433
                *fill++ = 0; *fill++ = 1; *fill++ = 5;
×
434
        }
435
//
436
//        Symmetry factors. We let Normalize do the multiplication.
437
//
438
        if ( eg->nsym != 1 ) {
×
439
                *fill++ = SNUMBER; *fill++ = 4; *fill++ = (WORD)eg->nsym; *fill++ = -1;
×
440
        }
441
        if ( eg->esym != 1 ) {
×
442
                *fill++ = SNUMBER; *fill++ = 4; *fill++ = (WORD)eg->esym; *fill++ = -1;
×
443
        }
444
        if ( eg->extperm != 1 ) {
×
445
                *fill++ = SNUMBER; *fill++ = 4; *fill++ = (WORD)eg->extperm; *fill++ = 1;
×
446
        }
447
//
448
//        finish it off
449
//
450
        while ( tail < tend ) *fill++ = *tail++;
×
451
        if ( eg->fsign < 0 ) fill[-1] = -fill[-1];
×
452
        *newterm = fill - newterm;
×
453
        AT.WorkPointer = fill;
×
454

455
//        MesPrint("<> %a",newterm[0],newterm);
456

457
        Generator(BHEAD newterm,info->level);
×
458
        AT.WorkPointer = oldworkpointer;
×
459
}
460

461
//        #] ProcessDiagram : 
462
//        #[ fendMG :
463

464
Bool fendMG(EGraph *eg, void *ti)
×
465
{
466
        DUMMYUSE(eg);
×
467
        DUMMYUSE(ti);
×
468
        return True;
×
469
}
470

471
//        #] fendMG : 
472
//        #[ ProcessTopology :
473

474
Bool ProcessTopology(EGraph *eg, void *ti)
11,172✔
475
{
476
//
477
//        This routine is called for each new topology.
478
//        New convention: return True;  generate the corresponding diagrams if needed
479
//                        return False; skip diagram generation (when asked for).
480
//
481
        TERMINFO *info = (TERMINFO *)ti;
11,172✔
482
#ifdef WITHEARLYVETO
483
        if ( ( ( info->flags & CHECKEXTERN ) == CHECKEXTERN ) && info->currentMODEL != NULL ) {
484
                int i, j;
485
                int numlegs, vect, edge;
486
                for ( i = 0; i < eg->nNodes; i++ ) {
487
                        if ( eg->isExternal(i) ) continue;
488
                        numlegs = eg->nodes[i]->deg;
489
                        for ( j = 0; j < numlegs; j++ ) {
490
                                edge = eg->nodes[i]->edges[j];
491
                                vect = ABS(edge)-1;
492
                                if ( vect < info->numextern && info->legcouple[vect][numlegs] == 0 ) {
493

494
//                                        This cannot be.
495

496
                                        info->numtopo++;
497
                                        return False;
498
                                }
499
                        }
500
                }
501
        }
502
#endif
503
        if ( ( info->flags & TOPOLOGIESONLY ) == 0 ) {
11,172✔
504
                info->numtopo++;
×
505
                return True;
×
506
        }
507
//
508
//        Now we are just generating topologies.
509
//
510
        GETIDENTITY
5,586✔
511
        WORD *term = info->term, *newterm, *oldworkpointer = AT.WorkPointer;
11,172✔
512
        WORD *tdia = term + info->diaoffset;
11,172✔
513
        WORD *tail = tdia + tdia[1];
11,172✔
514
        WORD *tend = term + *term;
11,172✔
515
        WORD *fill, *startfill;
11,172✔
516
        Model *model = (Model *)info->currentModel;
11,172✔
517
        MODEL *m = (MODEL *)info->currentMODEL;
11,172✔
518
        int i, j;
11,172✔
519
        int numlegs, vect, edge;
11,172✔
520

521
        newterm = term + *term;
11,172✔
522
        for ( i = 1; i < info->diaoffset; i++ ) newterm[i] = term[i];
11,172✔
523
        fill = newterm + info->diaoffset;
11,172✔
524
//
525
//        Now get the nodes
526
//
527
        for ( i = 0; i < eg->nNodes; i++ ) {
167,580✔
528
//
529
//                node_(number,momentum_1,...,momentum_n)
530
//
531
                numlegs = eg->nodes[i]->deg;
156,408✔
532
                startfill = fill;
156,408✔
533
                *fill++ = NODEFUNCTION;
156,408✔
534
                *fill++ = 0;
156,408✔
535
                FILLFUN(fill)
156,408✔
536
                *fill++ = -SNUMBER; *fill++ = i+1;
156,408✔
537
                if ( model != NULL && m != NULL ) {
156,408✔
538
                        if ( !eg->isExternal(i) ) {
156,408✔
539
                                WORD *afill = fill; *fill++ = 0; *fill++ = 1; FILLARG(fill)
134,064✔
540
                                WORD *cfill = fill; *fill++ = 0;
134,064✔
541
                                int cpl = 2*eg->nodes[i]->extloop+eg->nodes[i]->deg-2;
134,064✔
542
                                *fill++ = SYMBOL; *fill++ = 4;
134,064✔
543
                                *fill++ = m->couplings[0];
134,064✔
544
                                *fill++ = cpl;
134,064✔
545
                                *fill++ = 1; *fill++ = 1; *fill++ = 3;
134,064✔
546
                                *cfill = fill - cfill;
134,064✔
547
                                *afill = fill - afill;
134,064✔
548
                                if ( *afill == ARGHEAD+8 && afill[ARGHEAD+4] == 1 ) {
134,064✔
549
                                        fill = afill; *fill++ = -SYMBOL; *fill++ = afill[ARGHEAD+3];
134,064✔
550
                                }
551
                        }
552
                        else {
553
                                *fill++ = -SNUMBER;
22,344✔
554
                                *fill++ = 1;
22,344✔
555
                        }
556
                }
557
//
558
//                Now the momenta.
559
//
560
                for ( j = 0; j < numlegs; j++ ) {
580,944✔
561
                        edge = eg->nodes[i]->edges[j];
424,536✔
562
                        vect = ABS(edge)-1;
424,536✔
563
                        *fill++ = edge < 0 ? -MINVECTOR: -VECTOR;
424,536✔
564
                        if ( numlegs == 1 || vect < info->numextern ) { // Look up in set of external momenta
424,536✔
565
                                *fill++ = SetElements[Sets[info->externalset].first+vect];
44,688✔
566
                        }
567
                        else { // Look up in set of internal momenta set
568
                                *fill++ = SetElements[Sets[info->internalset].first+(vect-info->numextern)];
379,848✔
569
                        }
570
                }
571
                startfill[1] = fill-startfill;
156,408✔
572
        }
573
        if ( ( info->flags & WITHEDGES ) == WITHEDGES ) {
11,172✔
574
                for ( i = 0; i < eg->nEdges; i++ ) {
×
575
                        int n1 = eg->edges[i]->nodes[0];
×
576
                        int n2 = eg->edges[i]->nodes[1];
×
577
//                        int l1 = eg->edges[i]->nlegs[0];
578
//                        int l2 = eg->edges[i]->nlegs[1];
579
                        startfill = fill;
×
580
                        *fill++ = EDGE;
×
581
                        *fill++ = 0;
×
582
                        FILLFUN(fill)
×
583
                        *fill++ = -SNUMBER; *fill++ = i+1; // number of the edge
×
584
//
585
                        *fill++ = -VECTOR;
×
586
                        if ( i < info->numextern ) { // Look up in set of external momenta
×
587
                                *fill++ = SetElements[Sets[info->externalset].first+i];
×
588
                        }
589
                        else { // Look up in set of internal momenta set
590
                                *fill++ = SetElements[Sets[info->internalset].first+(i-eg->nExtern)];
×
591
                        }
592
//
593
                        *fill++ = -SNUMBER; *fill++ = n1+1; // number of the node from
×
594
                        *fill++ = -SNUMBER; *fill++ = n2+1; // number of the node to
×
595
                        startfill[1] = fill - startfill;
×
596
                }
597
        }
598
//
599
//        Block information
600
//
601
        if ( ( info->flags & WITHBLOCKS ) == WITHBLOCKS ) {
11,172✔
602
                for ( i = 0; i < eg->econn->nblocks; i++ ) {
×
603
                        startfill = fill;
×
604
                        *fill++ = BLOCK;
×
605
                        *fill++ = 0;
×
606
                        FILLFUN(fill);
×
607
                        *fill++ = -SNUMBER;
×
608
                        *fill++ = i+1;
×
609
                        *fill++ = -SNUMBER;
×
610
                        *fill++ = eg->econn->blocks[i].loop;
×
611
//
612
//                        Now we have to make a list of all nodes inside this block
613
//
614
                        int bnodes[GRCC_MAXNODES], k;
×
615
                        WORD *argfill = fill, *funfill;
×
616
                        *fill++ = 0; *fill++ = 0; FILLARG(fill)
×
617
                        *fill++ = 0;
×
618
                        for ( k = 0; k < GRCC_MAXNODES; k++ ) bnodes[k] = 0;
×
619
                        for ( k = 0; k < eg->econn->blocks[i].nmedges; k++ ) {
×
620
                                bnodes[eg->econn->blocks[i].edges[k][0]] = 1;
×
621
                                bnodes[eg->econn->blocks[i].edges[k][1]] = 1;
×
622
                        }
623
                        for ( k = 0; k < GRCC_MAXNODES; k++ ) {
×
624
                                if ( bnodes[k] == 0 ) continue;
×
625
//
626
//                                Now we put the node inside this argument.
627
//
628
                                funfill = fill;
×
629
                                *fill++ = NODEFUNCTION;
×
630
                                *fill++ = 0;
×
631
                                FILLFUN(fill)
×
632
                                *fill++ = -SNUMBER; *fill++ = k+1;
×
633
                                numlegs = eg->nodes[k]->deg;
×
634
                                for ( j = 0; j < numlegs; j++ ) {
×
635
                                        edge = eg->nodes[k]->edges[j];
×
636
                                        vect = ABS(edge)-1;
×
637
                                        *fill++ = -VECTOR;
×
638
                                        if ( numlegs == 1 || vect < info->numextern ) { // Look up in set of external momenta
×
639
                                                *fill++ = SetElements[Sets[info->externalset].first+vect];
×
640
                                        }
641
                                        else { // Look up in set of internal momenta set
642
                                                *fill++ = SetElements[Sets[info->internalset].first+(vect-info->numextern)];
×
643
                                        }
644
                                }
645
                                funfill[1] = fill-funfill;
×
646
                        }
647
                        *fill++ = 1; *fill++ = 1; *fill++ = 3;
×
648
                        *argfill = fill - argfill;
×
649
                        argfill[ARGHEAD] = argfill[0] - ARGHEAD;
×
650
                        startfill[1] = fill-startfill;
×
651
                }
652

653
//                if ( eg->econn->narticuls > 0 ) {
654
//                        startfill = fill;
655
//                        *fill++ = BLOCK;
656
//                        *fill++ = 0;
657
//                        FILLFUN(fill);
658
//                        for ( i = 0; i < eg->econn->snodes; i++ ) {
659
//                                if ( eg->econn->articuls[i] != 0 ) {
660
//                                        *fill++ = -SNUMBER;
661
//                                        *fill++ = i+1;
662
//                                }
663
//                        }
664
//                        startfill[1] = fill-startfill;
665
//                }
666
        }
667
        if ( ( info->flags & WITHONEPI ) == WITHONEPI ) {
11,172✔
668
                for ( i = 0; i < eg->econn->nopic; i++ ) {
×
669
                        startfill = fill;
×
670
                        *fill++ = ONEPI;
×
671
                        *fill++ = 0;
×
672
                        FILLFUN(fill);
×
673
                        *fill++ = -SNUMBER;
×
674
                        *fill++ = i+1;
×
675
                        *fill++ = -ONEPI;
×
676
                        for ( j = 0; j < eg->econn->opics[i].nnodes; j++ ) {
×
677
                                *fill++ = -SNUMBER;
×
678
                                *fill++ = eg->econn->opics[i].nodes[j]+1;
×
679
                        }
680
                        startfill[1] = fill-startfill;
×
681
                }
682
        }
683
//
684
//        Topology counter. We have exaggerated a bit with the eye on the far future.
685
//
686
        if ( info->numtopo < MAXPOSITIVE ) {
11,172✔
687
                *fill++ = TOPO; *fill++ = FUNHEAD+2; FILLFUN(fill)
11,172✔
688
                *fill++ = -SNUMBER; *fill++ = (WORD)(info->numtopo);
11,172✔
689
        }
690
        else if ( info->numtopo < FULLMAX-1 ) {
×
691
                *fill++ = TOPO; *fill++ = FUNHEAD+ARGHEAD+4; FILLFUN(fill)
×
692
                *fill++ = ARGHEAD+4; *fill++ = 0; FILLARG(fill)
×
693
                *fill++ = 4;
×
694
                *fill++ = (WORD)(info->numtopo & WORDMASK);
×
695
                *fill++ = 1; *fill++ = 3;
×
696
        }
697
        else {        // for now: science fiction
698
                *fill++ = TOPO; *fill++ = FUNHEAD+ARGHEAD+6; FILLFUN(fill)
×
699
                *fill++ = ARGHEAD+6; *fill++ = 0; FILLARG(fill)
×
700
                *fill++ = 6; *fill++ = (WORD)(info->numtopo >> BITSINWORD);
×
701
                *fill++ = (WORD)(info->numtopo & WORDMASK);
×
702
                *fill++ = 0; *fill++ = 1; *fill++ = 5;
×
703
        }
704
//
705
//        Symmetry factors. We let Normalize do the multiplication.
706
//
707
        if ( eg->nsym != 1 ) {
11,172✔
708
                *fill++ = SNUMBER; *fill++ = 4; *fill++ = (WORD)eg->nsym; *fill++ = -1;
4,988✔
709
        }
710
        if ( eg->esym != 1 ) {
11,172✔
711
                *fill++ = SNUMBER; *fill++ = 4; *fill++ = (WORD)eg->esym; *fill++ = -1;
8,196✔
712
        }
713
//
714
//        finish it off
715
//
716
        while ( tail < tend ) *fill++ = *tail++;
44,688✔
717
        if ( eg->fsign < 0 ) fill[-1] = -fill[-1];
11,172✔
718
        *newterm = fill - newterm;
11,172✔
719
        AT.WorkPointer = fill;
11,172✔
720

721
//MesPrint("<> %a",*newterm,newterm);
722

723
        Generator(BHEAD newterm,info->level);
11,172✔
724
        AT.WorkPointer = oldworkpointer;
11,172✔
725
        info->numtopo++;
11,172✔
726
        return False;
11,172✔
727
}
728

729
//        #] ProcessTopology : 
730
//        #[ GenDiagrams :
731

732
WORD GenDiagrams(PHEAD WORD *term, WORD level)
4✔
733
{
734
        Model *model;
4✔
735
        MODEL *m;
4✔
736
        Options *opt;
4✔
737
        Process *proc;
4✔
738
        int pid = 1, x;
4✔
739
        int babble = 0;    // Later we may set this at the FORM code level
4✔
740
        TERMINFO info;
4✔
741
        WORD inset,outset,*coupl,setnum,optionnumber = 0;
4✔
742
        int i, j, cpl[GRCC_MAXNCPLG];
4✔
743
        int ninitl, initlPart[GRCC_MAXLEGS], nfinal, finalPart[GRCC_MAXLEGS];
4✔
744
        for ( i = 0; i < GRCC_MAXNCPLG; i++ ) cpl[i] = 0;
20✔
745
//
746
//        Here we create an object of type Option and load it up.
747
//        Next we run the diagram generation on it.
748
//
749
        info.term = term;
4✔
750
        info.level = level;
4✔
751
        info.diaoffset = AR.funoffset;
4✔
752
        info.externalset = term[info.diaoffset+FUNHEAD+7];
4✔
753
        info.internalset = term[info.diaoffset+FUNHEAD+9];
4✔
754
        info.flags = 0;
4✔
755
        inset = term[info.diaoffset+FUNHEAD+3];
4✔
756
        outset = term[info.diaoffset+FUNHEAD+5];
4✔
757
        coupl = term + info.diaoffset + FUNHEAD + 10;
4✔
758
        if ( *coupl < 0 ) {
4✔
759
                if ( term[info.diaoffset+1] > FUNHEAD + 12 ) {
4✔
760
                        optionnumber = term[info.diaoffset+FUNHEAD+13];
4✔
761
                }
762
        }
763
        else {
764
                if ( term[info.diaoffset+1] > *coupl+FUNHEAD+10 )
×
765
                        optionnumber = term[info.diaoffset+*coupl+FUNHEAD+11];
×
766
        }
767
        setnum = term[info.diaoffset+FUNHEAD+1];
4✔
768

769
        m = AC.models[SetElements[Sets[setnum].first]];
4✔
770
        LoadModel(m);
4✔
771
        model = (Model *)m->grccmodel;
4✔
772

773
        info.currentModel = (void *)model;
4✔
774
        info.currentMODEL = (void *)m;
4✔
775
        info.numdia = 0;
4✔
776
        info.numtopo = 1;
4✔
777
        info.flags = optionnumber;
4✔
778

779
        opt = new Options();
4✔
780

781
        opt->setOutAG(ProcessDiagram, &info);
4✔
782
        opt->setOutMG(ProcessTopology, &info);
4✔
783
//        opt->setEndMG(fendMG, &info);
784

785
        opt->values[GRCC_OPT_1PI] = ( optionnumber & ONEPARTICLEIRREDUCIBLE ) == ONEPARTICLEIRREDUCIBLE;
4✔
786
        opt->values[GRCC_OPT_NoTadpole] = ( optionnumber & NOTADPOLES ) == NOTADPOLES;
4✔
787
//
788
//        Next are snails:
789
//
790
        opt->values[GRCC_OPT_No1PtBlock] = ( optionnumber & NOTADPOLES ) == NOTADPOLES;
4✔
791
//
792
        if ( ( optionnumber & WITHINSERTIONS ) == WITHINSERTIONS ) {
4✔
793
                opt->values[GRCC_OPT_No2PtL1PI] = True;
×
794
                opt->values[GRCC_OPT_NoAdj2PtV] = True;
×
795
                opt->values[GRCC_OPT_No2PtL1PI] = True;
×
796
        }
797
        else {
798
                opt->values[GRCC_OPT_NoAdj2PtV] = True;
4✔
799
        }
800
        opt->values[GRCC_OPT_SymmInitial] = ( optionnumber & WITHSYMMETRIZE ) == WITHSYMMETRIZE;
4✔
801
        opt->values[GRCC_OPT_SymmFinal] = ( optionnumber & WITHSYMMETRIZE ) == WITHSYMMETRIZE;
4✔
802

803
//        opt->values[GRCC_OPT_Block] = ( optionnumber & WITHBLOCKS ) == WITHBLOCKS;
804

805
        opt->setOutputF(False,"");
4✔
806
        opt->setOutputP(False,"");
4✔
807
        opt->printLevel(babble);
4✔
808

809
//        opt->values[GRCC_OPT_Step]       = GRCC_AGraph;
810

811
//        Load the various arrays.
812

813
    ninitl = Sets[inset].last - Sets[inset].first;
4✔
814
    for ( i = 0; i < ninitl; i++ ) {
12✔
815
        x = SetElements[Sets[inset].first+i];
8✔
816
        initlPart[i] = ConvertParticle(model,x);
8✔
817
                info.legcouple[i] = m->vertices[numParticle(m,x)]->couplings;
8✔
818
    }
819
    nfinal = Sets[outset].last - Sets[outset].first;
4✔
820
    for ( i = 0; i < nfinal; i++ ) {
4✔
821
        x = SetElements[Sets[outset].first+i];
×
822
        finalPart[i] = ConvertParticle(model,x);
×
823
                info.legcouple[i+ninitl] = m->vertices[numParticle(m,x)]->couplings;
×
824
    }
825
        info.numextern = ninitl + nfinal;
4✔
826
        for ( i = 2; i <= MAXLEGS; i++ ) {
80✔
827
                if ( m->legcouple[i] == 1 ) {
76✔
828
                        for ( j = 0; j < info.numextern; j++ ) {
24✔
829
                                if ( info.legcouple[j][i] == 0 ) { info.flags |= CHECKEXTERN; goto Go_on; }
16✔
830
                        }
831
                }
832
        }
833
Go_on:;
4✔
834
//
835
//        Now we have to sort out the coupling constants.
836
//        The argument at coupl can be of type -SNUMBER, -SYMBOL or generic
837
//        It has however already be tested for syntax.
838
//        Note that one cannot have 1 for the coupling constants.
839
//        In that case one should select 0 loops or something equivalent.
840
//
841
        if ( *coupl == -SNUMBER ) {        // Number of loops
4✔
842
//
843
//                This is the complicated case.
844
//                We have to compute the number of coupling constants and then
845
//                generate diagrams for all combinations with the proper power.
846
//
847
                int nc = coupl[1]*2 + ninitl + nfinal - 2;
4✔
848
                int *scratch = (int *)Malloc1(nc*sizeof(int),"DistrN");
4✔
849
                scratch[0] = -2; // indicating startup cq first call.
4✔
850

851
                if ( ( info.flags & TOPOLOGIESONLY ) == 0 ) {
4✔
852
                        while ( DistrN(nc,cpl,m->ncouplings,scratch) ) {
×
853
                                proc = new Process(pid, model, opt,
×
854
                               ninitl, initlPart, nfinal, finalPart, cpl);
×
855
                                delete proc;
×
856
                                info.numtopo = 1;
×
857
                        }
858
                }
859
                else {
860
                        cpl[0] = nc;
4✔
861
                        proc = new Process(pid, model, opt,
8✔
862
                              ninitl, initlPart, nfinal, finalPart, cpl);
4✔
863
                        delete proc;
4✔
864
                }
865
                M_free(scratch,"DistrN");
4✔
866
                opt->end();
4✔
867
                delete opt;
4✔
868
                return(0);
4✔
869
        }
870
        else if ( *coupl == -SYMBOL ) {        // Just a single power of one constant
×
871
                for ( i = 0; i < m->ncouplings; i++ ) {
×
872
                        if ( m->couplings[i] == coupl[1] ) {
×
873
                                cpl[i] = 1;
×
874
                                break;
×
875
                        }
876
                }
877
        }
878
        else {        // One term with powers of coupling constants
879
                WORD *t, *tstop;
×
880
                t = coupl + ARGHEAD+3;
×
881
                tstop = coupl+*coupl; tstop -= ABS(tstop[-1]);
×
882
                while ( t < tstop ) {
×
883
                        for ( i = 0; i < m->ncouplings; i++ ) {
×
884
                                if ( m->couplings[i] == *t ) {
×
885
                                        cpl[i] = t[1];
×
886
                                        break;
×
887
                                }
888
                        }
889
                        t += 2;
×
890
                }
891
        }
892
/*
893
        And now the generation:
894
*/
895
        proc = new Process(pid, model, opt,
×
896
                       ninitl, initlPart, nfinal, finalPart, cpl);
×
897
        opt->end();
×
898
        delete proc;
×
899
        delete opt;
×
900
        return(0);
901
}
902

903
//        #] GenDiagrams : 
904
//        #[ processVertex :
905

906
//        Routine is to be used recursively to work its way through a list
907
//        of possible vertices. The array of vertices is in TopoInf->vert
908
//        with TopoInf->nvert the number of possible vertices.
909
//        Currently we allow in TopoInf->vert only vertices with 3 or more edges.
910
//
911
//        We work with a point system. Each n-point vertex contributes n-2 points.
912
//        When all points are assigned, we can call mgraph->generate().
913
//
914
//        The number of vertices of a given number of edges is stored in
915
//        TopoInf->clnum[..] but the loop that determines how many there are
916
//        may be limited by the corresponding element in TopoInf->vertmax[level]
917

918
int processVertex(TOPOTYPE *TopoInf, int pointsremaining, int level)
×
919
{
920
        int i, j;
×
921

922
        for ( i = pointsremaining, j = 0; i >= 0; i -= TopoInf->vert[level]-2, j++ ) {
×
923
                if ( TopoInf->vertmax && TopoInf->vertmax[level] >= 0
×
924
                                         && j > TopoInf->vertmax[level] ) break;
×
925
                if ( i == 0 ) { // We got one!
×
926
                        TopoInf->cldeg[TopoInf->ncl] = TopoInf->vert[level];
×
927
                        TopoInf->clnum[TopoInf->ncl] = j;
×
928
                        TopoInf->clext[TopoInf->ncl] = 0;
×
929
                        TopoInf->ncl++;
×
930

931
                        MGraph *mgraph = new MGraph(1, TopoInf->ncl, TopoInf->cldeg,
×
932
                                                     TopoInf->clnum, TopoInf->clext,
×
933
                                                                 TopoInf->cmind, TopoInf->cmaxd, TopoInf->opt);
×
934

935
                    mgraph->generate();
×
936

937
                        delete mgraph;
×
938

939
                        TopoInf->ncl--;
×
940

941
                        break;
×
942
                }
943
                if ( level < TopoInf->nvert-1 ) {
×
944
                        if ( j > 0 ) {
×
945
                                TopoInf->cldeg[TopoInf->ncl] = TopoInf->vert[level];
×
946
                                TopoInf->clnum[TopoInf->ncl] = j;
×
947
                                TopoInf->clext[TopoInf->ncl] = 0;
×
948
                                TopoInf->ncl++;
×
949
                        }
950
                        if ( processVertex(TopoInf,i,level+1) < 0 ) return(-1);
×
951
                        if ( j > 0 ) { TopoInf->ncl--; }
×
952
                }
953
        }
954
        return(0);
955
}
956

957
//        #] processVertex : 
958
//        #[ GenTopologies :
959

960
#define TOPO_MAXVERT 10
961

962
WORD GenTopologies(PHEAD WORD *term, WORD level)
×
963
{
964
        Options *opt = new Options;
×
965
        int nlegs, nloops, i, identical;
×
966
        TERMINFO info;
×
967
        WORD *t, *t1, *tstop;
×
968
        TOPOTYPE TopoInf;
×
969
        SETS s;
×
970
//
971
        info.term = term;
×
972
        info.level = level;
×
973
        info.diaoffset = AR.funoffset;
×
974
        info.flags = 0;
×
975
 
976
        t = term + info.diaoffset;  // the function
×
977
        t1 = t + FUNHEAD;           // its arguments
×
978
        tstop = t + t[1];
×
979

980
        info.externalset = t1[7];
×
981
        info.internalset = t1[9];
×
982

983
        s = &(Sets[t1[5]]);
×
984
        TopoInf.nvert = s->last - s->first;
×
985
        TopoInf.vert  = &(SetElements[s->first]);
×
986

987
        nloops = t1[1];
×
988
        nlegs = t1[3];
×
989

990
        info.numextern = nlegs;
×
991

992
        for ( i = 0; i <= MAXLEGS; i++ ) { TopoInf.cmind[i] = TopoInf.cmaxd[i] = 0; }
×
993

994
        t1 += 10;
×
995
        if ( t1 < tstop && t1[0] == -SETSET ) {
×
996
                TopoInf.vertmax = &(SetElements[Sets[t1[1]].first]);
×
997
                t1 += 2;
×
998
        }
999
        else TopoInf.vertmax = NULL;
×
1000

1001
        info.flags |= TOPOLOGIESONLY;  // this is the topologies_ function after all.
×
1002
        if ( t1 < tstop && t1[0] == -SNUMBER ) {
×
1003
                if ( ( t1[1] &   NONODES ) ==   NONODES ) info.flags |=   NONODES;
×
1004
                if ( ( t1[1] & WITHEDGES ) == WITHEDGES ) info.flags |= WITHEDGES;
×
1005
                if ( ( t1[1] & WITHBLOCKS ) == WITHBLOCKS ) info.flags |= WITHBLOCKS;
×
1006
                if ( ( t1[1] & WITHONEPI ) == WITHONEPI ) info.flags |= WITHONEPI;
×
1007
                opt->values[GRCC_OPT_1PI] = ( t1[1] & ONEPARTICLEIRREDUCIBLE ) == ONEPARTICLEIRREDUCIBLE;
×
1008
//                opt->values[GRCC_OPT_NoTadpole] = ( t1[1] & NOTADPOLES ) == NOTADPOLES;
1009
                opt->values[GRCC_OPT_NoTadpole] = ( t1[1] & NOSNAILS ) == NOSNAILS;
×
1010
                opt->values[GRCC_OPT_No1PtBlock] = ( t1[1] & NOTADPOLES ) == NOTADPOLES;
×
1011
                opt->values[GRCC_OPT_NoExtSelf] = ( t1[1] & NOEXTSELF ) == NOEXTSELF;
×
1012

1013
                if ( ( t1[1] & WITHINSERTIONS ) == WITHINSERTIONS ) {
×
1014
                        opt->values[GRCC_OPT_No2PtL1PI] = True;
×
1015
                        opt->values[GRCC_OPT_NoAdj2PtV] = True;
×
1016
                        opt->values[GRCC_OPT_No2PtL1PI] = True;
×
1017
                }
1018
                opt->values[GRCC_OPT_SymmInitial] = ( t1[1] & WITHSYMMETRIZE ) == WITHSYMMETRIZE;
×
1019
        }
1020

1021
        info.numdia = 0;
×
1022
        info.numtopo = 1;
×
1023

1024
        opt->setOutAG(ProcessDiagram, &info);
×
1025
        opt->setOutMG(ProcessTopology, &info);
×
1026
//
1027
//        Now we should sum over all possible vertices and run MGraph for
1028
//        each combination. This is done by recursion in the processVertex routine
1029
//        First load up the relevant arrays.
1030
//
1031

1032
//        First the external nodes.
1033

1034
        if ( nlegs == -2 ) {
×
1035
                nlegs = 2;
×
1036
                identical = 1;
×
1037
        }
1038
        for ( i = 0; i < nlegs; i++ ) {
×
1039
                TopoInf.cldeg[i] = 1; TopoInf.clnum[i] = 1; TopoInf.clext[i] = -1;
×
1040
        }
1041
        int points = 2*nloops-2+nlegs;
×
1042

1043
        if ( identical == 1 ) {        /* Only propagator topologies..... */
×
1044
                nlegs = 1;
×
1045
                TopoInf.clnum[0] = 2;
×
1046
        }
1047
        TopoInf.ncl = nlegs;
×
1048
        TopoInf.opt = opt;
×
1049

1050
        if ( points >= MAXPOINTS ) {
×
1051
                MLOCK(ErrorMessageLock);
×
1052
                MesPrint("GenTopologies: %d loops and %d legs considered excessive",nloops,nlegs);
×
1053
                MUNLOCK(ErrorMessageLock);
×
NEW
1054
                TERMINATE(-1);
×
1055
        }
1056
        if ( processVertex(&TopoInf,points,0) != 0 ) {
×
1057
                MLOCK(ErrorMessageLock);
×
1058
                MesPrint("Called from GenTopologies with %d loops and %d legs",nloops,nlegs);
×
1059
                MUNLOCK(ErrorMessageLock);
×
NEW
1060
                TERMINATE(-1);
×
1061
        }
1062
        delete opt;
×
1063
        return(0);
×
1064
}
1065

1066
//        #] GenTopologies : 
1067

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc