OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
symbfac.c
Go to the documentation of this file.
1/*****************************************************************************
2/
3/ SPACE (SPArse Cholesky Elimination) Library: symbfac.c
4/
5/ author J"urgen Schulze, University of Paderborn
6/ created 09/15/99
7/
8/ This file contains code for the symbolical factorization.
9/
10******************************************************************************
11
12Data type: struct css
13 int neqs; number of equations
14 int nind; number of row subscripts in compressed format
15 int owned; does the object own vector nzlsub?
16 int *xnzl; start of column
17 int *nzlsub; row subscripts
18 int *xnzlsub; start of column's row subscripts
19
20 struct frontsub
21 elimtree_t *PTP; permuted elimination tree
22 int nind number of indices
23 int *xnzf; start of front subscripts
24 int *nzfsub front subscripts for permuted elimtree PTP
25
26 struct factorMtx
27 int nelem; number of nonzeros (incl. diagonal entries)
28 int *perm; permutation vector
29 FLOAT *nzl; vector of nonzeros (incl. diagonal entries)
30 css_t *css; compressed subscript structure of factorMtx
31 frontsub_t *frontsub; front subscripts
32Comments:
33Methods in lib/symbfac.c:
34- css = newCSS(int neqs, int nind, int owned);
35- void freeCSS(css_t *css);
36- css = setupCSSFromGraph(graph_t *G, int *perm, int *invp);
37- css = setupCSSFromFrontSubscripts(frontsub_t *frontsub);
38- frontsub = newFrontSubscripts(elimtree_t *PTP);
39- void freeFrontSubscripts(frontsub_t *frontsub);
40- void printFrontSubscripts(frontsub_t *frontsub);
41- frontsub = setupFrontSubscripts(elimtree_t *PTP, inputMtx_t *PAP);
42- L = newFactorMtx(int nelem);
43- void freeFactorMtx(factorMtx_t *L);
44- void printFactorMtx(factorMtx_t *L);
45- void initFactorMtx(factorMtx_t *L, inputMtx_t *PAP);
46- void initFactorMtxNEW(factorMtx_t *L, inputMtx_t *PAP);
47
48******************************************************************************/
49
50#include <space.h>
51
52
53/*****************************************************************************
54******************************************************************************/
55css_t*
56newCSS(PORD_INT neqs, PORD_INT nind, PORD_INT owned)
57{ css_t *css;
58
59 mymalloc(css, 1, css_t);
60 mymalloc(css->xnzl, (neqs+1), PORD_INT);
61 mymalloc(css->xnzlsub, neqs, PORD_INT);
62 if (owned)
63 { mymalloc(css->nzlsub, nind, PORD_INT); }
64 else
65 { css->nzlsub = NULL; }
66 css->neqs = neqs;
67 css->nind = nind;
68 css->owned = owned;
69
70 return(css);
71}
72
73
74/*****************************************************************************
75******************************************************************************/
76void
78{
79 free(css->xnzl);
80 free(css->xnzlsub);
81 if (css->owned)
82 free(css->nzlsub);
83 free(css);
84}
85
86
87/*****************************************************************************
88******************************************************************************/
89css_t*
91{ css_t *css;
92 PORD_INT *marker, *mergelink, *indices, *tmp, *xnzl, *xnzlsub, *nzlsub;
93 PORD_INT neqs, maxmem, u, v, col, mergecol, knz, mrk, beg, end;
94 PORD_INT fast, len, k, p, e, i, istart, istop;
95
96 neqs = G->nvtx;
97 maxmem = 2 * neqs;
98
99 /* -------------------------
100 set up the working arrays
101 ------------------------- */
102 mymalloc(marker, neqs, PORD_INT);
103 mymalloc(indices, neqs, PORD_INT);
104 mymalloc(mergelink, neqs, PORD_INT);
105 mymalloc(tmp, neqs, PORD_INT);
106 for (k = 0; k < neqs; k++)
107 marker[k] = mergelink[k] = -1;
108
109 /* -------------------------------------------------------
110 allocate storage for the compressed subscript structure
111 ------------------------------------------------------- */
112 css = newCSS(neqs, maxmem, TRUE);
113
114 xnzl = css->xnzl;
115 nzlsub = css->nzlsub;
116 xnzlsub = css->xnzlsub;
117
118 /* ------------------------------------------------------------
119 main loop: determine the subdiag. row indices of each column
120 ------------------------------------------------------------ */
121 xnzl[0] = 0;
122 beg = end = 0;
123 for (k = 0; k < neqs; k++)
124 { indices[0] = k;
125 knz = 1;
126
127 if ((mergecol = mergelink[k]) != -1) /* is k a leaf ??? */
128 { mrk = marker[mergecol];
129 fast = TRUE;
130 }
131 else
132 { mrk = k;
133 fast = FALSE;
134 }
135
136 /* --------------------------
137 original columns (indices)
138 -------------------------- */
139 u = invp[k];
140 istart = G->xadj[u];
141 istop = G->xadj[u+1];
142 for (i = istart; i < istop; i++)
143 { v = G->adjncy[i];
144 if ((col = perm[v]) > k)
145 { indices[knz++] = col;
146 if (marker[col] != mrk) fast = FALSE;
147 }
148 }
149
150 /* --------------------------
151 external columns (indices)
152 -------------------------- */
153 if ((fast) && (mergelink[mergecol] == -1))
154 { xnzlsub[k] = xnzlsub[mergecol] + 1;
155 knz = xnzl[mergecol+1] - xnzl[mergecol] - 1;
156 }
157 else
158 { for (i = 0; i < knz; i++)
159 marker[indices[i]] = k;
160 while (mergecol != -1)
161 { len = xnzl[mergecol+1] - xnzl[mergecol];
162 istart = xnzlsub[mergecol];
163 istop = istart + len;
164 for (i = istart; i < istop; i++)
165 { col = nzlsub[i];
166 if ((col > k) && (marker[col] != k))
167 { indices[knz++] = col;
168 marker[col] = k;
169 }
170 }
171 mergecol = mergelink[mergecol];
172 }
173 qsortUpInts(knz, indices, tmp);
174
175 /* ---------------------------------------------------
176 store indices in nzlsub; resize nzlsub if too small
177 --------------------------------------------------- */
178 beg = end;
179 xnzlsub[k] = beg;
180 end = beg + knz;
181 if (end > maxmem)
182 { maxmem += neqs;
183 myrealloc(nzlsub, maxmem, PORD_INT);
184 }
185 len = 0;
186 for (i = beg; i < end; i++)
187 nzlsub[i] = indices[len++];
188 }
189
190 /* ----------------------------
191 append column k to mergelink
192 ---------------------------- */
193 if (knz > 1)
194 { p = xnzlsub[k]+1;
195 e = nzlsub[p];
196 mergelink[k] = mergelink[e];
197 mergelink[e] = k;
198 }
199 xnzl[k+1] = xnzl[k] + knz;
200 }
201
202 /* -----------------------------
203 end of main loop: free memory
204 ----------------------------- */
205 free(marker); free(indices);
206 free(tmp); free(mergelink);
207
208 /* ------------------------------------------------------
209 finalize the compressed subscript structure and return
210 ------------------------------------------------------ */
211 css->nind = xnzlsub[neqs-1] + 1;
212 myrealloc(nzlsub, css->nind, PORD_INT);
213 css->nzlsub = nzlsub;
214 return(css);
215}
216
217
218/*****************************************************************************
219******************************************************************************/
220css_t*
222{ elimtree_t *PTP;
223 css_t *css;
224 PORD_INT *xnzf, *nzfsub, *ncolfactor, *xnzl, *xnzlsub;
225 PORD_INT nind, nvtx, K, beg, knz, firstcol, col;
226
227 PTP = frontsub->PTP;
228 xnzf = frontsub->xnzf;
229 nzfsub = frontsub->nzfsub;
230 nind = frontsub->nind;
231
232 nvtx = PTP->nvtx;
233 ncolfactor = PTP->ncolfactor;
234
235 /* -------------------------------------------------------
236 allocate storage for the compressed subscript structure
237 ------------------------------------------------------- */
238 css = newCSS(nvtx, nind, FALSE);
239 css->nzlsub = nzfsub;
240
241 xnzl = css->xnzl;
242 xnzlsub = css->xnzlsub;
243
244 /* ---------------------------------------
245 fill the compressed subscript structure
246 --------------------------------------- */
247 xnzl[0] = 0;
248 for (K = firstPostorder(PTP); K != -1; K = nextPostorder(PTP, K))
249 { beg = xnzf[K];
250 knz = xnzf[K+1] - beg;
251 firstcol = nzfsub[beg];
252 for (col = firstcol; col < firstcol + ncolfactor[K]; col++)
253 { xnzlsub[col] = beg++;
254 xnzl[col+1] = xnzl[col] + knz--;
255 }
256 }
257
258 return(css);
259}
260
261
262/*****************************************************************************
263******************************************************************************/
266{ frontsub_t *frontsub;
267 PORD_INT nfronts, nind;
268
269 nfronts = PTP->nfronts;
270 nind = nFactorIndices(PTP);
271
272 mymalloc(frontsub, 1, frontsub_t);
273 mymalloc(frontsub->xnzf, (nfronts+1), PORD_INT);
274 mymalloc(frontsub->nzfsub, nind, PORD_INT);
275
276 frontsub->PTP = PTP;
277 frontsub->nind = nind;
278
279 return(frontsub);
280}
281
282
283/*****************************************************************************
284******************************************************************************/
285void
287{
288 freeElimTree(frontsub->PTP);
289 free(frontsub->xnzf);
290 free(frontsub->nzfsub);
291 free(frontsub);
292}
293
294
295/*****************************************************************************
296******************************************************************************/
297void
299{ elimtree_t *PTP;
300 PORD_INT *xnzf, *nzfsub, *ncolfactor, *ncolupdate, *parent;
301 PORD_INT nfronts, root, K, count, i, istart, istop;
302
303 PTP = frontsub->PTP;
304 xnzf = frontsub->xnzf;
305 nzfsub = frontsub->nzfsub;
306
307 nfronts = PTP->nfronts;
308 root = PTP->root;
309 ncolfactor = PTP->ncolfactor;
310 ncolupdate = PTP->ncolupdate;
311 parent = PTP->parent;
312
313 printf("#fronts %d, root %d\n", nfronts, root);
314 for (K = firstPostorder(PTP); K != -1; K = nextPostorder(PTP, K))
315 { printf("--- front %d, ncolfactor %d, ncolupdate %d, parent %d\n",
316 K, ncolfactor[K], ncolupdate[K], parent[K]);
317 count = 0;
318 istart = xnzf[K];
319 istop = xnzf[K+1];
320 for (i = istart; i < istop; i++)
321 { printf("%5d", nzfsub[i]);
322 if ((++count % 16) == 0)
323 printf("\n");
324 }
325 if ((count % 16) != 0)
326 printf("\n");
327 }
328}
329
330
331/*****************************************************************************
332******************************************************************************/
335{ frontsub_t *frontsub;
336 PORD_INT *ncolfactor, *ncolupdate, *firstchild, *silbings, *vtx2front;
337 PORD_INT *xnza, *nzasub, *xnzf, *nzfsub;
338 PORD_INT *marker, *tmp, *first, *indices;
339 PORD_INT nvtx, nfronts, col, firstcol, knz;
340 PORD_INT u, i, istart, istop, K, J;
341
342 nvtx = PTP->nvtx;
343 nfronts = PTP->nfronts;
344 ncolfactor = PTP->ncolfactor;
345 ncolupdate = PTP->ncolupdate;
346 firstchild = PTP->firstchild;
347 silbings = PTP->silbings;
348 vtx2front = PTP->vtx2front;
349
350 xnza = PAP->xnza;
351 nzasub = PAP->nzasub;
352
353 /* -------------------------
354 set up the working arrays
355 ------------------------- */
356 mymalloc(marker, nvtx, PORD_INT);
357 mymalloc(tmp, nvtx, PORD_INT);
358 mymalloc(first, nfronts, PORD_INT);
359 for (i = 0; i < nvtx; i++)
360 marker[i] = -1;
361
362 /* --------------------------------
363 find the first column of a front
364 -------------------------------- */
365 for (u = nvtx-1; u >= 0; u--)
366 { K = vtx2front[u];
367 first[K] = u;
368 }
369
370 /* -----------------------------------------
371 allocate storage for the front subscripts
372 ----------------------------------------- */
373 frontsub = newFrontSubscripts(PTP);
374 xnzf = frontsub->xnzf;
375 nzfsub = frontsub->nzfsub;
376
377 knz = 0;
378 for (K = 0; K < nfronts; K++)
379 { xnzf[K] = knz;
380 knz += (ncolfactor[K] + ncolupdate[K]);
381 }
382 xnzf[K] = knz;
383
384 /* -------------------------------------------
385 postorder traversal of the elimination tree
386 ------------------------------------------- */
387 for (K = firstPostorder(PTP); K != -1; K = nextPostorder(PTP, K))
388 { knz = 0;
389 indices = nzfsub + xnzf[K];
390 firstcol = first[K];
391
392 /* -------------------------------------
393 internal columns (indices) of front K
394 ------------------------------------- */
395 for (col = firstcol; col < firstcol + ncolfactor[K]; col++)
396 { indices[knz++] = col;
397 marker[col] = K;
398 }
399
400 /* -------------------------------------
401 external columns (indices) of front K
402 ------------------------------------- */
403 for (J = firstchild[K]; J != -1; J = silbings[J])
404 { istart = xnzf[J];
405 istop = xnzf[J+1];
406 for (i = istart; i < istop; i++)
407 { col = nzfsub[i];
408 if ((col > firstcol) && (marker[col] != K))
409 { marker[col] = K;
410 indices[knz++] = col;
411 }
412 }
413 }
414
415 /* -------------------------------------
416 original columns (indices) of front K
417 ------------------------------------- */
418 for (u = 0; u < ncolfactor[K]; u++)
419 { istart = xnza[firstcol + u];
420 istop = xnza[firstcol + u + 1];
421 for (i = istart; i < istop; i++)
422 { col = nzasub[i];
423 if ((col > firstcol) && (marker[col] != K))
424 { marker[col] = K;
425 indices[knz++] = col;
426 }
427 }
428 }
429
430 /* ----------------
431 sort the indices
432 ---------------- */
433 qsortUpInts(knz, indices, tmp);
434 }
435
436 /* ----------------------
437 free memory and return
438 ---------------------- */
439 free(marker); free(tmp); free(first);
440 return(frontsub);
441}
442
443
444/*****************************************************************************
445******************************************************************************/
448{ factorMtx_t *L;
449
450 mymalloc(L, 1, factorMtx_t);
451 mymalloc(L->nzl, nelem, FLOAT);
452
453 L->nelem = nelem;
454 L->css = NULL;
455 L->frontsub = NULL;
456 L->perm = NULL;
457
458 return(L);
459}
460
461
462/*****************************************************************************
463******************************************************************************/
464void
466{
467 freeCSS(L->css);
469 free(L->nzl);
470 free(L->perm);
471 free(L);
472}
473
474
475/*****************************************************************************
476******************************************************************************/
477void
479{ css_t *css;
480 FLOAT *nzl;
481 PORD_INT *xnzl, *nzlsub, *xnzlsub;
482 PORD_INT neqs, nelem, nind, k, ksub, i, istart, istop;
483
484 nelem = L->nelem;
485 nzl = L->nzl;
486 css = L->css;
487
488 neqs = css->neqs;
489 nind = css->nind;
490 xnzl = css->xnzl;
491 nzlsub = css->nzlsub;
492 xnzlsub = css->xnzlsub;
493
494 printf("#equations %d, #elements (+diag.) %d, #indices (+diag.) %d\n",
495 neqs, nelem, nind);
496 for (k = 0; k < neqs; k++)
497 { printf("--- column %d\n", k);
498 ksub = xnzlsub[k];
499 istart = xnzl[k];
500 istop = xnzl[k+1];
501 for (i = istart; i < istop; i++)
502 printf(" row %5d, entry %e\n", nzlsub[ksub++], nzl[i]);
503 }
504}
505
506
507/*****************************************************************************
508******************************************************************************/
509void
511{ elimtree_t *PTP;
512 frontsub_t *frontsub;
513 css_t *css;
514 PORD_INT *ncolfactor;
515 FLOAT *nzl, *nza, *diag;
516 PORD_INT *xnzl, *nzlsub, *xnzlsub, *xnza, *nzasub, *xnzf, *nzfsub;
517 PORD_INT nelem, K, k, kstart, h, hstart, dis, i, istart, istop;
518 PORD_INT firstcol, lastcol;
519
520 nelem = L->nelem;
521 nzl = L->nzl;
522 css = L->css;
523 xnzl = css->xnzl;
524 nzlsub = css->nzlsub;
525 xnzlsub = css->xnzlsub;
526
527 frontsub = L->frontsub;
528 PTP = frontsub->PTP;
529 ncolfactor = PTP->ncolfactor;
530 xnzf = frontsub->xnzf;
531 nzfsub = frontsub->nzfsub;
532
533 diag = PAP->diag;
534 nza = PAP->nza;
535 xnza = PAP->xnza;
536 nzasub = PAP->nzasub;
537
538 /* ------------------------------------
539 set all numerical values of L to 0.0
540 ------------------------------------ */
541 for (i = 0; i < nelem; i++)
542 nzl[i] = 0.0;
543
544 /* --------------------------------------------
545 init. factor matrix with the nonzeros of PAP
546 -------------------------------------------- */
547 for (K = firstPostorder(PTP); K != -1; K = nextPostorder(PTP, K))
548 { firstcol = nzfsub[xnzf[K]];
549 lastcol = firstcol + ncolfactor[K];
550 for (k = firstcol; k < lastcol; k++)
551 { istart = xnza[k];
552 istop = xnza[k+1];
553 kstart = xnzl[k];
554 hstart = xnzlsub[k];
555 h = hstart;
556 for (i = istart; i < istop; i++)
557 { for (; nzlsub[h] != nzasub[i]; h++);
558 dis = h - hstart;
559 nzl[kstart+dis] = nza[i];
560 }
561 nzl[kstart] = diag[k];
562 }
563 }
564}
565
566
567/*****************************************************************************
568******************************************************************************/
569void
571{ elimtree_t *PTP;
572 frontsub_t *frontsub;
573 css_t *css;
574 PORD_INT *ncolfactor;
575 FLOAT *nzl, *nza, *diag, *entriesL;
576 PORD_INT *xnzl, *xnza, *nzasub, *xnzf, *nzfsub;
577 PORD_INT *tmp, neqs, nelem, K, k, len, row, i, istart, istop;
578 PORD_INT firstcol, lastcol;
579
580 nelem = L->nelem;
581 nzl = L->nzl;
582 css = L->css;
583 xnzl = css->xnzl;
584
585 frontsub = L->frontsub;
586 PTP = frontsub->PTP;
587 ncolfactor = PTP->ncolfactor;
588 xnzf = frontsub->xnzf;
589 nzfsub = frontsub->nzfsub;
590
591 neqs = PAP->neqs;
592 diag = PAP->diag;
593 nza = PAP->nza;
594 xnza = PAP->xnza;
595 nzasub = PAP->nzasub;
596
597 /* ------------------------
598 allocate working storage
599 ------------------------ */
600 mymalloc(tmp, neqs, PORD_INT);
601
602 /* ------------------------------------
603 set all numerical values of L to 0.0
604 ------------------------------------ */
605 for (i = 0; i < nelem; i++)
606 nzl[i] = 0.0;
607
608 /* --------------------------------------------
609 init. factor matrix with the nonzeros of PAP
610 -------------------------------------------- */
611 for (K = firstPostorder(PTP); K != -1; K = nextPostorder(PTP, K))
612 { len = 0;
613 istart = xnzf[K];
614 istop = xnzf[K+1];
615 for (i = istart; i < istop; i++)
616 tmp[nzfsub[i]] = len++;
617
618 firstcol = nzfsub[istart];
619 lastcol = firstcol + ncolfactor[K];
620 entriesL = nzl + xnzl[firstcol];
621 for (k = firstcol; k < lastcol; k++)
622 { istart = xnza[k];
623 istop = xnza[k+1];
624 for (i = istart; i < istop; i++)
625 { row = nzasub[i];
626 entriesL[tmp[row]] = nza[i];
627 }
628 entriesL[tmp[k]] = diag[k];
629 entriesL += --len;
630 }
631 }
632
633 /* --------------------
634 free working storage
635 -------------------- */
636 free(tmp);
637}
638
#define TRUE
Definition cblas_test.h:10
#define FALSE
Definition cblas_test.h:14
end[inform, rinform, sol, inst, schur, redrhs, pivnul_list, sym_perm, uns_perm, icntl, cntl, colsca_out, rowsca_out, keep_out, dkeep_out]
Definition dmumps.m:40
#define myrealloc(ptr, nr, type)
Definition macros.h:30
#define mymalloc(ptr, nr, type)
Definition macros.h:23
void qsortUpInts(PORD_INT, PORD_INT *, PORD_INT *)
Definition sort.c:98
PORD_INT nextPostorder(elimtree_t *, PORD_INT)
Definition tree.c:243
PORD_INT nFactorIndices(elimtree_t *)
Definition tree.c:874
PORD_INT firstPostorder(elimtree_t *)
Definition tree.c:213
void freeElimTree(elimtree_t *)
Definition tree.c:132
char root[ROOTLEN]
Definition rad2rad_c.c:124
PORD_INT * xnzlsub
Definition types.h:210
PORD_INT owned
Definition types.h:207
PORD_INT * nzlsub
Definition types.h:209
PORD_INT * xnzl
Definition types.h:208
PORD_INT neqs
Definition types.h:205
PORD_INT nind
Definition types.h:206
PORD_INT nfronts
Definition types.h:152
PORD_INT * silbings
Definition types.h:158
PORD_INT * parent
Definition types.h:156
PORD_INT * firstchild
Definition types.h:157
PORD_INT * ncolfactor
Definition types.h:154
PORD_INT root
Definition types.h:153
PORD_INT nvtx
Definition types.h:151
PORD_INT * vtx2front
Definition types.h:159
PORD_INT * ncolupdate
Definition types.h:155
frontsub_t * frontsub
Definition types.h:231
PORD_INT * perm
Definition types.h:228
FLOAT * nzl
Definition types.h:229
PORD_INT nelem
Definition types.h:227
css_t * css
Definition types.h:230
PORD_INT * nzfsub
Definition types.h:220
elimtree_t * PTP
Definition types.h:217
PORD_INT * xnzf
Definition types.h:219
PORD_INT nind
Definition types.h:218
PORD_INT * xadj
Definition types.h:35
PORD_INT nvtx
Definition types.h:31
PORD_INT * adjncy
Definition types.h:36
PORD_INT * xnza
Definition types.h:170
FLOAT * nza
Definition types.h:169
PORD_INT neqs
Definition types.h:166
PORD_INT * nzasub
Definition types.h:171
FLOAT * diag
Definition types.h:168
void freeCSS(css_t *css)
Definition symbfac.c:77
void initFactorMtx(factorMtx_t *L, inputMtx_t *PAP)
Definition symbfac.c:510
css_t * setupCSSFromGraph(graph_t *G, PORD_INT *perm, PORD_INT *invp)
Definition symbfac.c:90
css_t * newCSS(PORD_INT neqs, PORD_INT nind, PORD_INT owned)
Definition symbfac.c:56
void printFrontSubscripts(frontsub_t *frontsub)
Definition symbfac.c:298
void freeFrontSubscripts(frontsub_t *frontsub)
Definition symbfac.c:286
frontsub_t * setupFrontSubscripts(elimtree_t *PTP, inputMtx_t *PAP)
Definition symbfac.c:334
void freeFactorMtx(factorMtx_t *L)
Definition symbfac.c:465
void initFactorMtxNEW(factorMtx_t *L, inputMtx_t *PAP)
Definition symbfac.c:570
factorMtx_t * newFactorMtx(PORD_INT nelem)
Definition symbfac.c:447
css_t * setupCSSFromFrontSubscripts(frontsub_t *frontsub)
Definition symbfac.c:221
frontsub_t * newFrontSubscripts(elimtree_t *PTP)
Definition symbfac.c:265
void printFactorMtx(factorMtx_t *L)
Definition symbfac.c:478
double FLOAT
Definition types.h:23
#define PORD_INT
Definition types.h:20
struct _frontsub frontsub_t
struct _factorMtx factorMtx_t
struct _css css_t
struct _inputMtx inputMtx_t
struct _graph graph_t
struct _elimtree elimtree_t