DAJacCondRdW.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2 
3  DAFoam : Discrete Adjoint with OpenFOAM
4  Version : v3
5 
6 \*---------------------------------------------------------------------------*/
7 
8 #include "DAJacCondRdW.H"
9 
10 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
11 
12 namespace Foam
13 {
14 
15 defineTypeNameAndDebug(DAJacCondRdW, 0);
16 addToRunTimeSelectionTable(DAJacCon, DAJacCondRdW, dictionary);
17 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
18 
20  const word modelType,
21  const fvMesh& mesh,
22  const DAOption& daOption,
23  const DAModel& daModel,
24  const DAIndex& daIndex)
25  : DAJacCon(modelType, mesh, daOption, daModel, daIndex)
26 {
28  this->initializePetscVecs();
29 }
30 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
31 
32 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
33 
35 {
36  /*
37  Description:
38  Clear all members to avoid memory leak because we will initalize
39  multiple objects of DAJacCon. Here we need to delete all members
40  in the parent and child classes
41  */
42 
43  VecDestroy(&dRdWTPreallocOn_);
44  VecDestroy(&dRdWTPreallocOff_);
45  VecDestroy(&dRdWPreallocOn_);
46  VecDestroy(&dRdWPreallocOff_);
47 
48  this->clearDAJacConMembers();
49 }
51 {
52  /*
53  Description:
54  Initialize dRdWTPreallocOn_, dRdWTPreallocOff_, dRdWPreallocOn_,
55  dRdWPreallocOff_, and jacConColors_
56 
57  */
58 
59  // initialize the preallocation vecs
60  VecCreate(PETSC_COMM_WORLD, &dRdWTPreallocOn_);
61  VecSetSizes(dRdWTPreallocOn_, daIndex_.nLocalAdjointStates, PETSC_DECIDE);
62  VecSetFromOptions(dRdWTPreallocOn_);
63 
64  VecDuplicate(dRdWTPreallocOn_, &dRdWTPreallocOff_);
65  VecDuplicate(dRdWTPreallocOn_, &dRdWPreallocOn_);
66  VecDuplicate(dRdWTPreallocOn_, &dRdWPreallocOff_);
67 
68  // initialize coloring vectors
69 
70  // dRdW Colors
71  VecCreate(PETSC_COMM_WORLD, &jacConColors_);
72  VecSetSizes(jacConColors_, daIndex_.nLocalAdjointStates, PETSC_DECIDE);
73  VecSetFromOptions(jacConColors_);
74 
75  return;
76 }
77 
78 void DAJacCondRdW::setupJacConPreallocation(const dictionary& options)
79 {
80  /*
81  Description:
82  Setup the connectivity mat preallocation vectors:
83 
84  dRdWTPreallocOn_
85  dRdWTPreallocOff_
86  dRdWPreallocOn_
87  dRdWPreallocOff_
88 
89  Input:
90  options.stateResConInfo: a hashtable that contains the connectivity
91  information for dRdW, usually obtained from Foam::DAStateInfo
92  */
93 
94  HashTable<List<List<word>>> stateResConInfo;
95  options.readEntry<HashTable<List<List<word>>>>("stateResConInfo", stateResConInfo);
96 
97  label isPrealloc = 1;
98  this->setupdRdWCon(stateResConInfo, isPrealloc);
99 }
100 
101 void DAJacCondRdW::setupJacCon(const dictionary& options)
102 {
103  /*
104  Description:
105  Setup DAJacCon::jacCon_
106 
107  Input:
108  options.stateResConInfo: a hashtable that contains the connectivity
109  information for dRdW, usually obtained from Foam::DAStateInfo
110  */
111 
112  HashTable<List<List<word>>> stateResConInfo;
113  options.readEntry<HashTable<List<List<word>>>>("stateResConInfo", stateResConInfo);
114 
115  label isPrealloc = 0;
116  this->setupdRdWCon(stateResConInfo, isPrealloc);
117 }
118 
119 void DAJacCondRdW::initializeJacCon(const dictionary& options)
120 {
121  /*
122  Description:
123  Initialize the connectivity matrix and preallocate memory
124 
125  Input:
126  options: it is not used.
127  */
128 
129  MatCreate(PETSC_COMM_WORLD, &jacCon_);
130  MatSetSizes(
131  jacCon_,
134  PETSC_DETERMINE,
135  PETSC_DETERMINE);
136  MatSetFromOptions(jacCon_);
137 
139  jacCon_,
142  //MatSetOption(jacCon_, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);
143  MatSetUp(jacCon_);
144 
145  if (daOption_.getOption<label>("debug"))
146  {
147  Info << "Connectivity matrix initialized." << endl;
148  }
149 }
150 
152  const HashTable<List<List<word>>>& stateResConInfo,
153  const label isPrealloc)
154 {
155  /*
156  Description:
157  Calculates the state Jacobian connectivity mat DAJacCon::jacCon_ or
158  computing the preallocation vectors DAJacCondRdW::dRdWPreallocOn_ and
159  DAJacCondRdW::dRdWPreallocOff_
160 
161  Input:
162  stateResConInfo: a hashtable that contains the connectivity
163  information for dRdW, usually obtained from Foam::DAStateInfo
164 
165  isPrealloc == 1: calculate the preallocation vectors, else, calculate jacCon_
166 
167  Output:
168  DAJacCondRdW::dRdWPreallocOn_: preallocation vector that stores the number of
169  on-diagonal conectivity for each row
170 
171  DAJacCon::jacCon_: state Jacobian connectivity mat with dimension
172  sizeAdjStates by sizeAdjStates. jacCon_ has the same non-zero pattern as Jacobian mat.
173  The difference is that jacCon_ has values one for all non-zero values, so jacCon_
174  may look like this
175 
176  1 1 0 0 1 0
177  1 1 1 0 0 1
178  0 1 1 1 0 0
179  jacCon_ = 1 0 1 1 1 0
180  0 1 0 1 1 1
181  0 0 1 0 0 1
182 
183  Example:
184  The way setupJacCon works is that we call the DAJacCon::addStateConnections function
185  to add connectivity for each row of DAJacCon::jacCon_.
186 
187  Here we need to loop over all cellI and add a certain number levels of connected states.
188  If the connectivity list reads:
189 
190  stateResConInfo
191  {
192  "URes"
193  {
194  {"U", "p", "phi"}, // level 0 connectivity
195  {"U", "p", "phi"}, // level 1 connectivity
196  {"U"}, // level 2 connectivity
197  }
198  }
199 
200  and the cell topology with a inter-proc boundary cen be either of the following:
201  CASE 1:
202  ---------
203  | cellQ |
204  -----------------------
205  | cellP | cellJ | cellO | <------ proc1
206  ------------------------------------------------ <----- inter-processor boundary
207  | cellT | cellK | cellI | cellL | cellU | <------ proc0
208  -----------------------------------------
209  | cellN | cellM | cellR |
210  ------------------------
211  | cellS |
212  ---------
213 
214  CASE 2:
215  ---------
216  | cellQ | <------ proc1
217  -------------------------------------------------- <----- inter-processor boundary
218  | cellP | cellJ | cellO | <------ proc0
219  -----------------------------------------
220  | cellT | cellK | cellI | cellL | cellU |
221  -----------------------------------------
222  | cellN | cellM | cellR |
223  ------------------------
224  | cellS |
225  ---------
226 
227  Then, to add the connectivity correctly, we need to add all levels of connected
228  states for cellI.
229  Level 0 connectivity is straightforward becasue we don't need
230  to provide connectedStatesInterProc
231 
232  To add level 1 connectivity, we need to:
233  set connectedLevelLocal = 1
234  set connectedStatesLocal = {U, p}
235  set connectedStatesInterProc = {{U,p}, {U}}
236  set addFace = 1
237  NOTE: we need set level 1 and level 2 con in connectedStatesInterProc because the
238  north face of cellI is a inter-proc boundary and there are two levels of connected
239  state on the other side of the inter-proc boundary for CASE 1. This is the only chance we
240  can add all two levels of connected state across the boundary for CASE 1. For CASE 2, we won't
241  add any level 1 inter-proc states because non of the faces for cellI are inter-proc
242  faces so calling DAJacCon::addBoundaryFaceConnections for cellI won't add anything
243 
244  To add level 2 connectivity, we need to
245  set connectedLevelLocal = 2
246  set connectedStatesLocal = {U}
247  set connectedStatesInterProc = {{U}}
248  set addFace = 0
249  NOTE 1: we need only level 2 con (U) for connectedStatesInterProc because if we are in CASE 1,
250  the level 2 of inter-proc states have been added. For CASE 2, we only need to add cellQ
251  by calling DAJacCon::addBoundaryFaceConnections with cellJ
252  NOTE 2: If we didn't call two levels of connectedStatesInterProc in the previous call for
253  level 1 con, we can not add it for connectedLevelLocal = 2 becasue for CASE 2 there is no
254  inter-proc boundary for cellI
255 
256  NOTE: how to provide connectedLevelLocal, connectedStatesLocal, and connectedStatesInterProc
257  are done in this function
258 
259  */
260 
261  label globalIdx;
262  // connectedStatesP: one row matrix that stores the actual connectivity,
263  // element value 1 denotes a connected state. connectedStatesP is then used to
264  // assign dRdWPreallocOn or dRdWCon
265  Mat connectedStatesP;
266 
267  PetscInt nCols;
268  const PetscInt* cols;
269  const PetscScalar* vals;
270 
271  PetscInt nColsID;
272  const PetscInt* colsID;
273  const PetscScalar* valsID;
274 
275  if (isPrealloc)
276  {
277  VecZeroEntries(dRdWPreallocOn_);
278  VecZeroEntries(dRdWPreallocOff_);
279  VecZeroEntries(dRdWTPreallocOn_);
280  VecZeroEntries(dRdWTPreallocOff_);
281  }
282 
283  if (daOption_.getOption<label>("debug"))
284  {
285  if (isPrealloc)
286  {
287 
288  Info << "Computing preallocating vectors for Jacobian connectivity mat" << endl;
289  }
290  else
291  {
292  Info << "Setup Jacobian connectivity mat" << endl;
293  }
294  }
295 
296  // loop over all cell residuals, we bascially need to compute all
297  // the input parameters for the DAJacCondRdW::addStateConnections function, then call
298  // the function to get connectedStatesP (matrix that contains one row of connectivity
299  // in DAJacCondRdW::jacCon_). Check DAJacCondRdW::addStateConnections for detail usages
301  {
302  // get stateName and residual names
303  word stateName = daIndex_.adjStateNames[idxI];
304  word resName = stateName + "Res";
305 
306  // check if this state is a cell state, we do surfaceScalarState residuals separately
307  if (daIndex_.adjStateType[stateName] == "surfaceScalarState")
308  {
309  continue;
310  }
311 
312  // maximal connectivity level information
313  // Note that stateResConInfo starts with level zero,
314  // so the maxConLeve is its size minus one
315  label maxConLevel = stateResConInfo[resName].size() - 1;
316 
317  // if it is a vectorState, set compMax=3
318  label compMax = 1;
319  if (daIndex_.adjStateType[stateName] == "volVectorState")
320  {
321  compMax = 3;
322  }
323 
324  forAll(mesh_.cells(), cellI)
325  {
326  for (label comp = 0; comp < compMax; comp++)
327  {
328 
329  // zero the connections
330  this->createConnectionMat(&connectedStatesP);
331 
332  // now add the con. We loop over all the connectivity levels
333  forAll(stateResConInfo[resName], idxJ) // idxJ: con level
334  {
335 
336  // set connectedStatesLocal: the locally connected state variables for this level
337  wordList connectedStatesLocal(0);
338  forAll(stateResConInfo[resName][idxJ], idxK)
339  {
340  word conName = stateResConInfo[resName][idxJ][idxK];
341  // Exclude surfaceScalarState when appending connectedStatesLocal
342  // whether to add it depends on addFace parameter
343  if (daIndex_.adjStateType[conName] != "surfaceScalarState")
344  {
345  connectedStatesLocal.append(conName);
346  }
347  }
348 
349  // set connectedStatesInterProc: the globally connected state variables for this level
350  List<List<word>> connectedStatesInterProc;
351  if (idxJ == 0)
352  {
353  // pass a zero list, no need to add interProc connecitivity for level 0
354  connectedStatesInterProc.setSize(0);
355  }
356  else if (idxJ != maxConLevel)
357  {
358  connectedStatesInterProc.setSize(maxConLevel - idxJ + 1);
359  for (label k = 0; k < maxConLevel - idxJ + 1; k++)
360  {
361  label conSize = stateResConInfo[resName][k + idxJ].size();
362  for (label l = 0; l < conSize; l++)
363  {
364  word conName = stateResConInfo[resName][k + idxJ][l];
365  // Exclude surfaceScalarState when appending connectedStatesLocal
366  // whether to add it depends on addFace parameter
367  if (daIndex_.adjStateType[conName] != "surfaceScalarState")
368  {
369  connectedStatesInterProc[k].append(conName);
370  }
371  }
372  }
373  }
374  else
375  {
376  connectedStatesInterProc.setSize(1);
377  label conSize = stateResConInfo[resName][maxConLevel].size();
378  for (label l = 0; l < conSize; l++)
379  {
380  word conName = stateResConInfo[resName][maxConLevel][l];
381  // Exclude surfaceScalarState when appending connectedStatesLocal
382  // whether to add it depends on addFace parameter
383  if (daIndex_.adjStateType[conName] != "surfaceScalarState")
384  {
385  connectedStatesInterProc[0].append(conName);
386  }
387  }
388  }
389 
390  // check if we need to addFace for this level
391  label addFace = 0;
392  forAll(stateInfo_["surfaceScalarStates"], idxK)
393  {
394  word conName = stateInfo_["surfaceScalarStates"][idxK];
395  if (DAUtility::isInList<word>(conName, stateResConInfo[resName][idxJ]))
396  {
397  addFace = 1;
398  }
399  }
400 
401  // special treatment for pressureInletVelocity. No such treatment is needed
402  // for dFdW because we have added phi in their conInfo
403  if (DAUtility::isInList<word>("pressureInletVelocity", daField_.specialBCs)
404  && this->addPhi4PIV(stateName, cellI, comp))
405  {
406  addFace = 1;
407  }
408 
409  // Add connectivity
410  this->addStateConnections(
411  connectedStatesP,
412  cellI,
413  idxJ,
414  connectedStatesLocal,
415  connectedStatesInterProc,
416  addFace);
417 
418  //Info<<"lv: "<<idxJ<<" locaStates: "<<connectedStatesLocal<<" interProcStates: "
419  // <<connectedStatesInterProc<<" addFace: "<<addFace<<endl;
420  }
421 
422  // get the global index of the current state for the row index
423  globalIdx = daIndex_.getGlobalAdjointStateIndex(stateName, cellI, comp);
424 
425  if (isPrealloc)
426  {
432  connectedStatesP,
433  globalIdx);
434  }
435  else
436  {
438  jacCon_,
439  connectedStatesP,
440  globalIdx);
441  }
442  }
443  }
444  }
445 
446  // loop over all face residuals
447  forAll(stateInfo_["surfaceScalarStates"], idxI)
448  {
449  // get stateName and residual names
450  word stateName = stateInfo_["surfaceScalarStates"][idxI];
451  word resName = stateName + "Res";
452 
453  // maximal connectivity level information
454  label maxConLevel = stateResConInfo[resName].size() - 1;
455 
456  forAll(mesh_.faces(), faceI)
457  {
458 
459  //zero the connections
460  this->createConnectionMat(&connectedStatesP);
461 
462  // Get the owner and neighbour cells for this face
463  label idxO = -1, idxN = -1;
464  if (faceI < daIndex_.nLocalInternalFaces)
465  {
466  idxO = mesh_.owner()[faceI];
467  idxN = mesh_.neighbour()[faceI];
468  }
469  else
470  {
471  label relIdx = faceI - daIndex_.nLocalInternalFaces;
472  label patchIdx = daIndex_.bFacePatchI[relIdx];
473  label faceIdx = daIndex_.bFaceFaceI[relIdx];
474 
475  const UList<label>& pFaceCells = mesh_.boundaryMesh()[patchIdx].faceCells();
476  idxN = pFaceCells[faceIdx];
477  }
478 
479  // now add the con. We loop over all the connectivity levels
480  forAll(stateResConInfo[resName], idxJ) // idxJ: con level
481  {
482 
483  // set connectedStatesLocal: the locally connected state variables for this level
484  wordList connectedStatesLocal(0);
485  forAll(stateResConInfo[resName][idxJ], idxK)
486  {
487  word conName = stateResConInfo[resName][idxJ][idxK];
488  // Exclude surfaceScalarState when appending connectedStatesLocal
489  // whether to add it depends on addFace parameter
490  if (daIndex_.adjStateType[conName] != "surfaceScalarState")
491  {
492  connectedStatesLocal.append(conName);
493  }
494  }
495 
496  // set connectedStatesInterProc: the globally connected state variables for this level
497  List<List<word>> connectedStatesInterProc;
498  if (idxJ == 0)
499  {
500  // pass a zero list, no need to add interProc connecitivity for level 0
501  connectedStatesInterProc.setSize(0);
502  }
503  else if (idxJ != maxConLevel)
504  {
505  connectedStatesInterProc.setSize(maxConLevel - idxJ + 1);
506  for (label k = 0; k < maxConLevel - idxJ + 1; k++)
507  {
508  label conSize = stateResConInfo[resName][k + idxJ].size();
509  for (label l = 0; l < conSize; l++)
510  {
511  word conName = stateResConInfo[resName][k + idxJ][l];
512  // Exclude surfaceScalarState when appending connectedStatesLocal
513  // whether to add it depends on addFace parameter
514  if (daIndex_.adjStateType[conName] != "surfaceScalarState")
515  {
516  connectedStatesInterProc[k].append(conName);
517  }
518  }
519  }
520  }
521  else
522  {
523  connectedStatesInterProc.setSize(1);
524  label conSize = stateResConInfo[resName][maxConLevel].size();
525  for (label l = 0; l < conSize; l++)
526  {
527  word conName = stateResConInfo[resName][maxConLevel][l];
528  // Exclude surfaceScalarState when appending connectedStatesLocal
529  // whether to add it depends on addFace parameter
530  if (daIndex_.adjStateType[conName] != "surfaceScalarState")
531  {
532  connectedStatesInterProc[0].append(conName);
533  }
534  }
535  }
536 
537  // check if we need to addFace for this level
538  label addFace = 0;
539  forAll(stateInfo_["surfaceScalarStates"], idxK)
540  {
541  word conName = stateInfo_["surfaceScalarStates"][idxK];
542  // NOTE: we need special treatment for boundary faces for level>0
543  // since addFace for boundary face should add one more extra level of faces
544  // This is because we only have idxN for a boundary face while the idxO can
545  // be on the other side of the inter-proc boundary
546  // In this case, we need to use idxJ-1 instead of idxJ information to tell whether to addFace
547  label levelCheck;
548  if (faceI < daIndex_.nLocalInternalFaces or idxJ == 0)
549  {
550  levelCheck = idxJ;
551  }
552  else
553  {
554  levelCheck = idxJ - 1;
555  }
556 
557  if (DAUtility::isInList<word>(conName, stateResConInfo[resName][levelCheck]))
558  {
559  addFace = 1;
560  }
561  }
562 
563  // special treatment for pressureInletVelocity. No such treatment is needed
564  // for dFdW because we have added phi in their conInfo
565  if (DAUtility::isInList<word>("pressureInletVelocity", daField_.specialBCs)
566  && this->addPhi4PIV(stateName, faceI))
567  {
568  addFace = 1;
569  }
570 
571  // Add connectivity for idxN
572  this->addStateConnections(
573  connectedStatesP,
574  idxN,
575  idxJ,
576  connectedStatesLocal,
577  connectedStatesInterProc,
578  addFace);
579 
580  if (faceI < daIndex_.nLocalInternalFaces)
581  {
582  // Add connectivity for idxO
583  this->addStateConnections(
584  connectedStatesP,
585  idxO,
586  idxJ,
587  connectedStatesLocal,
588  connectedStatesInterProc,
589  addFace);
590  }
591 
592  //Info<<"lv: "<<idxJ<<" locaStates: "<<connectedStatesLocal<<" interProcStates: "
593  // <<connectedStatesInterProc<<" addFace: "<<addFace<<endl;
594  }
595 
596  // NOTE: if this faceI is on a coupled patch, the above connectivity is not enough to
597  // cover the points on the other side of proc domain, we need to add 3 lvs of cells here
598  if (faceI >= daIndex_.nLocalInternalFaces)
599  {
600  label relIdx = faceI - daIndex_.nLocalInternalFaces;
601  label patchIdx = daIndex_.bFacePatchI[relIdx];
602 
603  label maxLevel = stateResConInfo[resName].size();
604 
605  if (mesh_.boundaryMesh()[patchIdx].coupled())
606  {
607 
608  label bRow = this->getLocalCoupledBFaceIndex(faceI);
609  label bRowGlobal = daIndex_.globalCoupledBFaceNumbering.toGlobal(bRow);
610  MatGetRow(stateBoundaryCon_, bRowGlobal, &nCols, &cols, &vals);
611  MatGetRow(stateBoundaryConID_, bRowGlobal, &nColsID, &colsID, &valsID);
612  for (label i = 0; i < nCols; i++)
613  {
614  PetscInt idxJ = cols[i];
615  label val = round(vals[i]);
616  // we are going to add some selective states with connectivity level <= 3
617  // first check the state
618  label stateID = round(valsID[i]);
619  word conName = daIndex_.adjStateNames[stateID];
620  label addState = 0;
621  // NOTE: we use val-1 here since phi actually has 3 levels of connectivity
622  // however, when we assign stateResConInfo, we ignore the level 0
623  // connectivity since they are idxN and idxO
624  if (val != 10 && val < maxLevel + 1)
625  {
626  if (DAUtility::isInList<word>(conName, stateResConInfo[resName][val - 1]))
627  {
628  addState = 1;
629  }
630  }
631  if (addState == 1 && val < maxLevel + 1 && val > 0)
632  {
633  this->setConnections(connectedStatesP, idxJ);
634  }
635  }
636  MatRestoreRow(stateBoundaryCon_, bRowGlobal, &nCols, &cols, &vals);
637  MatRestoreRow(stateBoundaryConID_, bRowGlobal, &nColsID, &colsID, &valsID);
638  }
639  }
640 
641  // get the global index of the current state for the row index
642  globalIdx = daIndex_.getGlobalAdjointStateIndex(stateName, faceI);
643 
644  if (isPrealloc)
645  {
651  connectedStatesP,
652  globalIdx);
653  }
654  else
655  {
657  jacCon_,
658  connectedStatesP,
659  globalIdx);
660  }
661  }
662  }
663 
664  if (isPrealloc)
665  {
666  VecAssemblyBegin(dRdWPreallocOn_);
667  VecAssemblyEnd(dRdWPreallocOn_);
668  VecAssemblyBegin(dRdWPreallocOff_);
669  VecAssemblyEnd(dRdWPreallocOff_);
670  VecAssemblyBegin(dRdWTPreallocOn_);
671  VecAssemblyEnd(dRdWTPreallocOn_);
672  VecAssemblyBegin(dRdWTPreallocOff_);
673  VecAssemblyEnd(dRdWTPreallocOff_);
674 
675  //output the matrix to a file
676  wordList writeJacobians;
677  daOption_.getAllOptions().readEntry<wordList>("writeJacobians", writeJacobians);
678  if (writeJacobians.found("dRdWTPrealloc"))
679  {
680  DAUtility::writeVectorASCII(dRdWTPreallocOn_, "dRdWTPreallocOn");
681  DAUtility::writeVectorASCII(dRdWTPreallocOff_, "dRdWTPreallocOff");
682  DAUtility::writeVectorASCII(dRdWPreallocOn_, "dRdWPreallocOn");
683  DAUtility::writeVectorASCII(dRdWPreallocOff_, "dRdWPreallocOff");
684  }
685  }
686  else
687  {
688  MatAssemblyBegin(jacCon_, MAT_FINAL_ASSEMBLY);
689  MatAssemblyEnd(jacCon_, MAT_FINAL_ASSEMBLY);
690 
691  //output the matrix to a file
692  wordList writeJacobians;
693  daOption_.getAllOptions().readEntry<wordList>("writeJacobians", writeJacobians);
694  if (writeJacobians.found("dRdWCon"))
695  {
696  //DAUtility::writeMatRowSize(jacCon_, "dRdWCon");
698  }
699  }
700 
701  if (daOption_.getOption<label>("debug"))
702  {
703  if (isPrealloc)
704  {
705  Info << "Preallocating state Jacobian connectivity mat: finished!" << endl;
706  }
707  else
708  {
709  Info << "Setup state Jacobian connectivity mat: finished!" << endl;
710  }
711  }
712 }
713 
715  Vec preallocOnProc,
716  Vec preallocOffProc,
717  Vec preallocOnProcT,
718  Vec preallocOffProcT,
719  Mat connections,
720  const label row)
721 {
722  /*
723  Description:
724  Compute the matrix allocation vector based on one row connection mat
725 
726  Input:
727  connections: a one row matrix that contains all the nonzeros for one
728  row of DAJacCon::jacCon_
729 
730  row: which row to add for the preallocation vector
731 
732  Output:
733  preallocOnProc: the vector that contains the number of nonzeros for each row
734  in dRdW (on-diagonal block elements)
735 
736  preallocOffProc: the vector that contains the number of nonzeros for each row
737  in dRdW (off-diagonal block elements)
738 
739  preallocOnProcT: the vector that contains the number of nonzeros for each row
740  in dRdWT (on-diagonal block elements)
741 
742  preallocOffProcT: the vector that contains the number of nonzeros for each row
743  in dRdWT (off-diagonal block elements)
744 
745  */
746  PetscScalar v = 1.0;
747  PetscInt nCols;
748  const PetscInt* cols;
749  const PetscScalar* vals;
750 
751  MatAssemblyBegin(connections, MAT_FINAL_ASSEMBLY);
752  MatAssemblyEnd(connections, MAT_FINAL_ASSEMBLY);
753 
754  // Compute the transposed case
755  // in this case connections represents a single column, so we need to
756  // increment the counter in each row with a non-zero entry.
757 
758  label colMin = daIndex_.globalAdjointStateNumbering.toGlobal(0);
759  label colMax = colMin + daIndex_.nLocalAdjointStates;
760  // by construction rows should be limited to local rows
761  MatGetRow(connections, 0, &nCols, &cols, &vals);
762 
763  // for the non-transposed case just sum up the row.
764  // count up the total number of non zeros in this row
765  label totalCount = 0; //2
766  label localCount = 0;
767  //int idx;
768  for (label j = 0; j < nCols; j++)
769  {
770  // int idx = cols[j];
771  scalar val = vals[j];
772  if (DAUtility::isValueCloseToRef(val, 1.0))
773  {
774  // We can compute the first part of the non-transposed row here.
775  totalCount++;
776  label idx = cols[j];
777  // Set the transposed version as well
778  if (colMin <= idx && idx < colMax)
779  {
780  //this entry is a local entry, increment the corresponding row
781  VecSetValue(preallocOnProcT, idx, v, ADD_VALUES);
782  localCount++;
783  }
784  else
785  {
786  // this is an off proc entry.
787  VecSetValue(preallocOffProcT, idx, v, ADD_VALUES);
788  }
789  }
790  }
791 
792  label offProcCount = totalCount - localCount;
793  VecSetValue(preallocOnProc, row, localCount, INSERT_VALUES);
794  VecSetValue(preallocOffProc, row, offProcCount, INSERT_VALUES);
795 
796  // restore the row of the matrix
797  MatRestoreRow(connections, 0, &nCols, &cols, &vals);
798  MatDestroy(&connections);
799 
800  return;
801 }
802 
804  Mat dRMat,
805  const Vec preallocOnProc,
806  const Vec preallocOffProc) const
807 {
808  /*
809  Description:
810  Preallocate memory for dRMat.
811 
812  Input:
813  preallocOnProc, preallocOffProc: the on and off diagonal nonzeros for
814  dRMat
815 
816  Output:
817  dRMat: matrix to preallocate memory for
818  */
819 
820  PetscScalar normOn, normOff;
821  VecNorm(preallocOnProc, NORM_2, &normOn);
822  VecNorm(preallocOffProc, NORM_2, &normOff);
823  PetscScalar normSum = normOn + normOff;
824  if (normSum < 1.0e-10)
825  {
826  FatalErrorIn("preallocateJacobianMatrix")
827  << "preallocOnProc and preallocOffProc are not allocated!"
828  << abort(FatalError);
829  }
830 
831  PetscScalar *onVec, *offVec;
832  PetscInt onSize[daIndex_.nLocalAdjointStates], offSize[daIndex_.nLocalAdjointStates];
833 
834  VecGetArray(preallocOnProc, &onVec);
835  VecGetArray(preallocOffProc, &offVec);
836  for (label i = 0; i < daIndex_.nLocalAdjointStates; i++)
837  {
838  onSize[i] = round(onVec[i]);
839  if (onSize[i] > daIndex_.nLocalAdjointStates)
840  {
841  onSize[i] = daIndex_.nLocalAdjointStates;
842  }
843  offSize[i] = round(offVec[i]) + 5; // reserve 5 more?
844  }
845 
846  VecRestoreArray(preallocOnProc, &onVec);
847  VecRestoreArray(preallocOffProc, &offVec);
848 
849  // MatMPIAIJSetPreallocation(dRMat,NULL,preallocOnProc,NULL,preallocOffProc);
850  // MatSeqAIJSetPreallocation(dRMat,NULL,preallocOnProc);
851 
852  MatMPIAIJSetPreallocation(dRMat, NULL, onSize, NULL, offSize);
853  MatSeqAIJSetPreallocation(dRMat, NULL, onSize);
854 
855  return;
856 }
857 
859  Mat dRMat,
860  const label transposed) const
861 {
862  /*
863  Description:
864  Call the DAJacCondRdW::preallocateJacobianMatrix function with the
865  correct vectors, depending on transposed
866 
867  Input:
868  transposed: whether the state Jacobian mat is transposed, i.e., it
869  is for dRdW or dRdWT (transposed)
870 
871  Output:
872  dRMat: the matrix to preallocate
873  */
874  if (transposed)
875  {
877  }
878  else
879  {
881  }
882 }
883 
884 } // End namespace Foam
885 
886 // ************************************************************************* //
Foam::DAJacCon
Definition: DAJacCon.H:34
Foam::DAJacCondRdW::preallocatedRdW
virtual void preallocatedRdW(Mat dRMat, const label transposed) const
preallocate memory for dRdW using the computed preallocation vectors
Definition: DAJacCondRdW.C:858
forAll
forAll(pseudoP.boundaryField(), patchI)
Definition: solvePseudoPEqn.H:10
Foam::DAJacCondRdW::setupdRdWCon
void setupdRdWCon(const HashTable< List< List< word >>> &stateResConInfo, const label isPrealloc)
Definition: DAJacCondRdW.C:151
Foam::DAIndex::globalAdjointStateNumbering
globalIndex globalAdjointStateNumbering
Definition: DAIndex.H:167
Foam::DAJacCon::mesh_
const fvMesh & mesh_
fvMesh
Definition: DAJacCon.H:49
Foam::DAJacCon::jacCon_
Mat jacCon_
Jacobian connectivity mat.
Definition: DAJacCon.H:79
Foam::DAIndex::bFacePatchI
labelList bFacePatchI
Definition: DAIndex.H:110
Foam::DAJacCon::daOption_
const DAOption & daOption_
DAOption object.
Definition: DAJacCon.H:52
Foam::DAJacCon::clearDAJacConMembers
void clearDAJacConMembers()
clear members in DAJacCon
Definition: DAJacCon.H:164
Foam::DAOption
Definition: DAOption.H:29
DAJacCondRdW.H
Foam::DAIndex::getGlobalAdjointStateIndex
label getGlobalAdjointStateIndex(const word stateName, const label idxI, const label comp=-1) const
get global adjoint index for a given state name, cell/face indxI and its component (optional,...
Definition: DAIndex.C:661
Foam::DAJacCondRdW::clear
virtual void clear()
clear members in parent and child objects
Definition: DAJacCondRdW.C:34
Foam::DAJacCondRdW::dRdWTPreallocOff_
Vec dRdWTPreallocOff_
Definition: DAJacCondRdW.H:34
daOption
DAOption daOption(mesh, pyOptions_)
Foam::DAJacCondRdW::setupJacConPreallocation
virtual void setupJacConPreallocation(const dictionary &options)
calculate the
Definition: DAJacCondRdW.C:78
Foam::DAField::specialBCs
wordList specialBCs
a list that contains the names of detected special boundary conditions
Definition: DAField.H:125
Foam::DAJacCondRdW::initializePetscVecs
void initializePetscVecs()
initialize petsc vectors
Definition: DAJacCondRdW.C:50
Foam::DAJacCon::getLocalCoupledBFaceIndex
label getLocalCoupledBFaceIndex(const label localFaceI) const
given a local face index, return the local index of the coupled boundary face
Definition: DAJacCon.C:637
Foam::DAOption::getOption
classType getOption(const word key) const
get an option from subDict and key
Definition: DAOption.H:92
Foam::DAIndex::adjStateType
HashTable< word > adjStateType
hash table of adjoint state types, e.g., volVectorState for a given state name
Definition: DAIndex.H:77
Foam::DAJacCon::initializeStateBoundaryCon
void initializeStateBoundaryCon()
initialize state boundary connection
Definition: DAJacCon.C:88
Foam::DAJacCon::setupJacobianConnections
void setupJacobianConnections(Mat conMat, Mat connections, const label idxI)
assign values in connections to a specific row idxI in conMat
Definition: DAJacCon.C:126
Foam::DAUtility::isValueCloseToRef
static label isValueCloseToRef(const scalar val, const scalar refVal, const scalar tol=1.0e-6)
check whether a value is close to a reference value by a tolerance
Definition: DAUtility.C:651
Foam::DAOption::getAllOptions
const dictionary & getAllOptions() const
return a reference of allOptions_ dictionary
Definition: DAOption.H:56
mesh
fvMesh & mesh
Definition: createRefsHeatTransfer.H:4
Foam::DAJacCondRdW::dRdWPreallocOn_
Vec dRdWPreallocOn_
Definition: DAJacCondRdW.H:35
Foam::DAIndex::globalCoupledBFaceNumbering
globalIndex globalCoupledBFaceNumbering
Definition: DAIndex.H:171
Foam::DAIndex
Definition: DAIndex.H:32
Foam::DAIndex::adjStateNames
List< word > adjStateNames
list of adjoint state names for a specific solver
Definition: DAIndex.H:74
dafoam_plot3dtransform.vals
vals
Definition: dafoam_plot3dtransform.py:39
Foam::DAModel
Definition: DAModel.H:59
k
dimensionedScalar & k
Definition: createRefsHeatTransfer.H:6
Foam
Definition: multiFreqScalarFvPatchField.C:144
Foam::DAJacCon::stateBoundaryCon_
Mat stateBoundaryCon_
matrix to store boundary connectivity levels for state Jacobians
Definition: DAJacCon.H:70
Foam::DAJacCon::daField_
DAField daField_
DAField object.
Definition: DAJacCon.H:64
Foam::DAJacCon::daIndex_
const DAIndex & daIndex_
DAIndex object.
Definition: DAJacCon.H:58
Foam::DAIndex::nLocalInternalFaces
label nLocalInternalFaces
local internal face size
Definition: DAIndex.H:98
Foam::DAJacCondRdW::dRdWTPreallocOn_
Vec dRdWTPreallocOn_
Definition: DAJacCondRdW.H:33
Foam::DAUtility::writeMatrixBinary
static void writeMatrixBinary(const Mat matIn, const word prefix)
write petsc matrix in binary format
Definition: DAUtility.C:355
Foam::DAJacCondRdW::initializeJacCon
virtual void initializeJacCon(const dictionary &options)
initialize the state Jacobian connectivity matrix
Definition: DAJacCondRdW.C:119
Foam::DAJacCondRdW::DAJacCondRdW
DAJacCondRdW(const word modelType, const fvMesh &mesh, const DAOption &daOption, const DAModel &daModel, const DAIndex &daIndex)
Definition: DAJacCondRdW.C:19
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(DAFvSource, 0)
Foam::DAUtility::writeVectorASCII
static void writeVectorASCII(const Vec vecIn, const word prefix)
write petsc vector in ascii format
Definition: DAUtility.C:291
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(DAFvSource, DAFvSourceActuatorDisk, dictionary)
daModel
DAModel daModel(mesh, daOption)
Foam::DAJacCon::createConnectionMat
void createConnectionMat(Mat *connectedStates)
allocate connectedState matrix
Definition: DAJacCon.C:161
Foam::DAJacCon::setConnections
void setConnections(Mat conMat, const label idx) const
add value 1 for the colume idx to conMat
Definition: DAJacCon.C:553
Foam::DAJacCon::stateBoundaryConID_
Mat stateBoundaryConID_
matrix to store boundary connectivity ID for state Jacobians
Definition: DAJacCon.H:73
Foam::DAJacCondRdW::allocateJacobianConnections
void allocateJacobianConnections(Vec preallocOnProc, Vec preallocOffProc, Vec preallocOnProcT, Vec preallocOffProcT, Mat connections, const label row)
compute preallocation vectors
Definition: DAJacCondRdW.C:714
daIndex
DAIndex daIndex(mesh, daOption, daModel)
Foam::DAJacCon::jacConColors_
Vec jacConColors_
jacCon matrix colors
Definition: DAJacCon.H:82
Foam::DAJacCondRdW::setupJacCon
virtual void setupJacCon(const dictionary &options)
assign 1 to all non-zero elements for the Jacobian connecitivyt matrix
Definition: DAJacCondRdW.C:101
Foam::DAJacCon::addStateConnections
void addStateConnections(Mat connections, const label cellI, const label connectedLevelLocal, const wordList connectedStatesLocal, const List< List< word >> connectedStateInterProc, const label addFace)
a high-level function to add connected state column indices to the connectivity matrix
Definition: DAJacCon.C:188
Foam::DAIndex::bFaceFaceI
labelList bFaceFaceI
Definition: DAIndex.H:116
Foam::DAJacCon::stateInfo_
HashTable< wordList > stateInfo_
the regState_ list from DAStateInfo object
Definition: DAJacCon.H:67
Foam::DAIndex::nLocalAdjointStates
label nLocalAdjointStates
number of local adjoint states (including all cells and faces)
Definition: DAIndex.H:145
Foam::DAJacCondRdW::dRdWPreallocOff_
Vec dRdWPreallocOff_
Definition: DAJacCondRdW.H:36
Foam::DAJacCondRdW::preallocateJacobianMatrix
void preallocateJacobianMatrix(Mat dRMat, const Vec preallocOnProc, const Vec preallocOffProc) const
compute preallocation vectors
Definition: DAJacCondRdW.C:803