ODT
|
#include <meshManager.h>
Public Member Functions | |
void | adaptGrid (int iLower, int iUpper) |
bool | operator() (const int &a, const int &b) const |
void | adaptAfterSufficientDiffTime (const double &time, double &tLastDA, int &cLastDA, double &dtCUmax) |
void | adaptEddyRegionOfMesh (const double &time, double &tLastDA, int &cLastDA) |
void | splitCell (const int isplt, const int nsplt, const vector< double > &cellFaces) |
void | merge2cells (const int imrg, const bool LconstVolume=false) |
void | enforceDomainSize () |
void | removeFaceNearZero () |
void | makeCellWithZeroSymmetric () |
void | splitCellWithZero () |
** Create cell with r=0 at its center | |
void | setGridDxc (const domain *line, vector< double > &dxc, double C) |
void | setGridDx (const domain *line, vector< double > &dx) |
void | setGridFromDxc (const vector< double > &dxc2) |
void | init (domain *p_domn, const vector< dv * > p_phi) |
meshManager () | |
~meshManager () | |
Public Attributes | |
domain * | domn |
pointer to odt domain to adapt | |
vector< dv * > | phi |
vector of pointers to domainvariable objects | |
vector< double > | dx |
vector of cell sizes | |
vector< int > | mark |
dummy small cell index array for sorting | |
vector< double > | xf |
vector of cell face positions | |
vector< vector< double > > | yf |
vector of cell values | |
vector< double > | xnf |
vector of new cell face positions | |
vector< double > | X |
vector of cell center positions | |
int | ngrd |
local number of grid points | |
int | ngrdf |
local number of grid faces | |
int | iLower |
region of grid to adapt (the cell w/ left eddy edge) | |
int | iUpper |
region of grid to adapt (the cell w/ right eddy edge) | |
double | posLower |
physical region of eddy (lower bound) | |
double | posUpper |
physical region of eddy (upper bound) | |
vector< double > | lastDA |
constant (unif) mesh to list time of last adapt | |
Private Member Functions | |
void | adaptGrid_details (const int iLower, const int iUpper) |
void | mergeSmallCells () |
void | mergeSmallCellsMP () |
void | impose2point5rule () |
void | splitLargeCells () |
void | fix2point5offender (const int mPos, const int &iglobal) |
void | setDxArray () |
int | findPos (const vector< double > &x, const double val, const int &istart) |
void | interp1pt (const vector< double > &x, const vector< double > &y, const double &xval, double &yval, int &istart) |
void | interpVec (const vector< double > &x, const vector< double > &y, const vector< double > &xn, vector< double > &yn) |
double | calcDistance (const vector< double > &x, const vector< vector< double > > &y, vector< double > &sDist) |
void | set_iLower_iUpper () |
void | updateDA (const double &time, double &tLastDA, int &cLastDA, int iStart, int iEnd) |
Mesh adaptor class. This class will adapt 1D domains. The specific domain to adapt is set through a pointer. A single variable profile is used for adaption of a given domain (e.g. velocity or mixture fraction). The mesh adapter has several parts (see adaptODTgrid). This is meant to be called after eddy events or significant diffusion. The adaption inserts or removes cells depending on cell size, gradients, curvature, and neighboring cell sizes.
Definition at line 31 of file meshManager.h.
|
inline |
Definition at line 138 of file meshManager.h.
|
inline |
Definition at line 139 of file meshManager.h.
void meshManager::adaptAfterSufficientDiffTime | ( | const double & | time, |
double & | tLastDA, | ||
int & | cLastDA, | ||
double & | dtCUmax ) |
Adapt regions of the mesh depending on age since last adaption. Start at cell index cLastDA in the "lastDA" domain (grid) and search right and left for old cells. Update these cells (tag them with current time), then adapt them. Then cLastDA (from Update) is the next oldest cell not just adapted. Search left and right for a new region, and so on until nothing on the grid is too old.
time | input: current time. |
tLastDA | input/output: time of last diffusion advancement. |
cLastDA | input/output: cell index. |
dtCUmax | input/output: the time increment of eddy trial time advancement before we diffuse |
Definition at line 1131 of file meshManager.cc.
void meshManager::adaptEddyRegionOfMesh | ( | const double & | time, |
double & | tLastDA, | ||
int & | cLastDA ) |
Adapt region of mesh and keep track of start/stop indices
iStart | input/output: starting index of region to adapt. |
iEnd | input/output: ending index of region to adapt. |
dtCUmax | input/output: the time increment of eddy trial time advancement before we diffuse |
time | input: current time. |
tLastDA | input/output: time of last diffusion advancement. |
cLastDA | input/output: cell index. |
Definition at line 1255 of file meshManager.cc.
void meshManager::adaptGrid | ( | int | iLowerDummy, |
int | iUpperDummy ) |
User interface to the mesh adapter.
iLowerDummy | input: lower cell to adapt from (approx). |
iUpperDummy | input: upper cell to adapt to (approx). |
Definition at line 40 of file meshManager.cc.
|
private |
Adapt the grid
iLowerDummy | input: lower cell to adapt from (approx). |
iUpperDummy | input: upper cell to adapt to (approx). |
Definition at line 138 of file meshManager.cc.
|
private |
Computes and returns total distance (length) along a curve specified by vectors x and y
x | input: vector of cell positions |
y | input: vector of vector cell values for profiles (phi's) to compare |
sDist | input: vector that stores the running distance along the curve |
Definition at line 937 of file meshManager.cc.
void meshManager::enforceDomainSize | ( | ) |
Enforce the domain size by chopping a domain that is too big, or expanding a domain that is too small. This is called in the microMixer where the grid cells expand or contract (updateGrid), and also after the mesher when we have merged all cells.
Note, this only works for open domains (one or two sides).
Definition at line 1278 of file meshManager.cc.
|
private |
Given a position, find an index (use with pos)
x | input: vector of cell positions |
val | input: location which is converted to index |
istart | input: start looking at this index |
Definition at line 869 of file meshManager.cc.
|
private |
Marks cells that offend their neighbors with respect to the 2.5 rule
Routine is recursive. Returns if the test is passed, or if we are at the ends of the domain. \n If it starts with no "small cells" routine, it won't create any small cells.\n The order of operations doesn't matter. \n Find the larger of mPos and its next neighbor (mPos+1) and split that cell on the side of the smaller cell. Split it nsplit times in half. \n So, <tt><pre> | || ==> | * : : || </pre></tt> when splitting twice.\n Then go to the opposite side of the split cell (marked with \c * above) and compare to its neighbor on the other side. In this example, we would "mark" the cell before the \c * and call the same routine on it. \n Hence, we can traverse through the domain. Generally you keep traversing till satisfy the rule or hit the edge. To keep going in one direction the cells need to keep increasing (so we won't go too far since motion implies geometric growth). You also will stop traversing when you run into a smaller cell. \n Consider:\n <tt><pre> || | || || | 0 1 2 3 4 5 6 mark offenders: 0 2 3 4 5 Start at 0: 0 vs 1 --> split 1 once || : | || || | 0 1 2 3 4 5 6 7 2 vs 3 --> split 3 once || : | : || || | 0 1 2 3 4 5 6 7 8 4 vs 5 --> split 4 once || : | : : || || | 0 1 2 3 4 5 6 7 8 9 3 vs 4 --> pass --> done now do next in mark array (which was updated as we went to ( X 3 6 7 8) Start at 3: 3 vs 4 --> pass (trivially) --> done Start at 6: 6 vs 7 --> split 7 once || : | : : || : || | 0 1 2 3 4 5 6 7 8 9 10 8 vs 9 --> pass (say) --> done: mark array ( X X X 7 9 ) Start at 7: 7 vs 8 --> pass Start at 9: 9 vs 10 --> split 4 times || : | : : || : || : : : : | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 14 at the end --> DONE </pre></tt>
mPos | input: marks a cell that offends its next neighbor with respect to the 2.5 rule. |
iglobal | input: is the index of which loop it is on in the mark arrary, for the mark array update. (Could just leave this out and do all of them but only need to update subsequent ones). |
Definition at line 770 of file meshManager.cc.
|
private |
Imposes the 2.5 rule for Mesh adaption to the grid.
Definition at line 681 of file meshManager.cc.
meshManager initialization function
p_domn | input: set domain pointer with. |
p_phi | input: set vector pointer with. |
Definition at line 24 of file meshManager.cc.
|
private |
Linear interpolation of a single point, given two vectors x
and y
.
x | input: vector of cell positions |
y | input: vector of cell values |
xval | input: position to interpolate |
yval | output: value at interpolated position |
istart | output: start looking at this index (for findPos) |
Definition at line 892 of file meshManager.cc.
|
private |
Linear interpolation of a vector of points (call interp1pt each time)
x | input: vector of cell positions |
y | input: vector of cell values |
xn | input: vector of positions to interp to |
yn | output: vector of interpolated values |
Definition at line 915 of file meshManager.cc.
void meshManager::makeCellWithZeroSymmetric | ( | ) |
Make the cell that contains 0.0 be symmetric so that the cell center is zero. Only for cylindrical or spherical Based on a code by Juan.
Definition at line 1481 of file meshManager.cc.
void meshManager::merge2cells | ( | const int | imrg, |
const bool | LconstVolume = false ) |
Operates on the domain Merges conservatively.
imrg | input: merge imrg with imrg+1 |
LconstVolume | input: if true, do the merge without allowing a change in cell volume. (default is false. True when we merge small cells at edges after enforcing domain length so that the volume doesn't change, requiring another enforce domain length, etc.) |
Below, the notation is |—1—|-—2-—| --> |------—3----—|
For temporal flows: Merge with constant volume before and after. V3 = V1 + V2 (V = volume = dxc = delta(x^c)). Let m1 = rho1*V1 and m2 = rho2*V2 (Mass conservation implies: m3 = m1 + m2) For all scalars except rho: s3 = (s1*m1 + s2*m2) / (m1+m2) Then set rho3 based on these scalars (like rho=MP/RT, say) Set posf and pos for V3 (for posf, just delete the middle face).
This will not preserve mass conservation: V3 is set, and rho3 is computed from rho=MP/RT instead of from rho3 = (m1+m2)/V3. (Or, if mass is conserved, it implies a pressure/temperature change).
Version without conserving volume: Let m1 = rho1*V1 and m2 = rho2*V2 For all scalars except rho: s3 = (s1*m1 + s2*m2) / (m1+m2) Then set rho3 based on these scalars (like rho=MP/RT, say) Set V3 = (m1+m2)/rho3. Set posf and pos for V3 (domain expands or contracts and the whole profiles shift).
For spatial flows: Merge with constant volume before and after. V3 = V1 + V2 Let m1 = rho1*u1*V1 and m2 = rho2*u2*V2 (Mass flux conservation implies: m3 = m1 + m2) Set all scalars except rho and u: s3 = (s1*m1 + s2*m2)/(m1+m2). (Well, do u, but it will be redundant as overwritten below). Set rho3 based on scalars (like rho=MP/RT, say). Set u3 = (m1+m2)/(rho3*V3). (This step conserves mass flux). Set posf and pos for V3 (for posf, just delete the middle face).
This will conserve mass flux and all scalar fluxes, but not momentum flux, because we required volume conservation.
Version without conserving volume: Let m1 = rho1*u1*V1 and m2 = rho2*u2*V2 Set all scalars except rho: s3 = (s1*m1 + s2*m2)/(m1+m2), INCLUDING u3. (Now momentum is conserved). Set rho3 based on scalars (like rho=MP/RT, say). Set V3 = (m1+m2)/(rho3 * u3) Set posf and pos for V3. Here, expand/contract about the expansion center.
This conserves everything, but does "bad" things: If you change a cell volume, then you shift the profile throughout the domain. That is especially bad if all you are trying to do is Merge two cells together. Example: velocity profile. (This was done with a toy problem in the code: set prof, merge cells). 4 / \ / \ / \ 3 5 / \ / \ 1-----2 6----7----8 4 / \ / \ / \ 3 5 / \ / \ 1-----2 6----7 - Suppose you merge cell 5 with cell 6. - Let the u=0 in cells 1, 2, 6-8. - Assume constant density. - Then m2=0, so u3 = u1, That is the merged cell has u = u5. - Also, V3 = V1 and we delete cell V2 (that is, cell 6), so there is a net loss of volume on the domain. - We remove half the volume from each side of the domain, which is equivalent to contracting about the contraction center. - In a planar flow, this means we simply shift the whole profile to the right, We would then extend the end cells to fill the domain. But this is clearly weird. By merging cells, we have shifted the whole domain and not changed the profile shape. If you merge cell 1 with two, it moves the other direction. Now, normally you can't have a zero velocity in spatial flow, but with "small" velocity, similar behavior happens. This shifting of the domain caused profiles to wander unphysically during simulation. A trip map on one side will cause more merging/splitting on that side...
NOTE: not conserving moment (constant volume formulation) causded major momentum conservation issues in jet flows.
Definition at line 1078 of file meshManager.cc.
|
private |
Cells that are too small are merged with their neighbors. Cells here are marked simply as whether they are small or not. The subsequent merging is with either neighbor. Elsewhere marked cells are to be merged with the right neighbor. Small cells are usually generated by triplet map events that compress the grid (or by accelerating flows in spatial domains that compress the grid). Mark the small cells by filling mark (member) with indicies in grid Merge the small cells in size order. That is, initial size order, not accounting for intermediate changes. This eliminates directional bias too. So rearrange the small cell indicies into sorted order, scMark (local). Then loop over each small cell till big enough, merging with its smaller neighbor. The smaller neighbor may or may not be a small cell. When merge cells, need to decrement larger indicies (cells) in the scMark array, and delete cells from scMark if a small cell is merged with another. No special treatment for periodic boundaries. Periodic is the same as nonperiodic. The periodic boundary position is maintained, and no merging occurs across a periodic boundary (which would move the boundary from zero).
Definition at line 418 of file meshManager.cc.
|
private |
This function does the same as mergeSmallCell() excapt that it checks, in addition, the phase of the merged cell. If there is no opportunity for merging the cell, it is skipped.
ToDo: If there is a too small cell and both neigbor cells have different phases, the cell has to be handeled. For this case, I have no idea how to handle.
Definition at line 543 of file meshManager.cc.
|
inline |
Definition at line 63 of file meshManager.h.
void meshManager::removeFaceNearZero | ( | ) |
If a face is too close to r=0, remove it by merging. Only for cylindrical or spherical
Definition at line 1461 of file meshManager.cc.
|
private |
Finds iLower and iUpper based on the new cell face positions
Definition at line 374 of file meshManager.cc.
|
private |
Resizes and sets the dx array to reflect the correct distances.
Definition at line 852 of file meshManager.cc.
void meshManager::setGridDx | ( | const domain * | line, |
vector< double > & | dx ) |
Set the cell volume vectors: dx = x_e - x_w
line | input: pointer to domain to use (eddyline or domain) |
dx | input/output: vector of cell sizes. |
Definition at line 1449 of file meshManager.cc.
void meshManager::setGridDxc | ( | const domain * | line, |
vector< double > & | dxc, | ||
double | C ) |
Set the cell volume vectors: dxc = | |x_e|^c - |x_w|^c |.
line | input: pointer to domain to use (eddyline or domain) |
dxc | input/output: vector of cell volumes. |
Definition at line 1432 of file meshManager.cc.
void meshManager::setGridFromDxc | ( | const vector< double > & | dxc2 | ) |
If a face is too close to r=0, remove it by merging. Only for cylindrical or spherical
Definition at line 1593 of file meshManager.cc.
void meshManager::splitCell | ( | const int | isplt, |
const int | nsplt, | ||
const vector< double > & | cellFaces ) |
Operates on the domain. Splits cells at interior elements of cellFaces vector (conservative).
isplt | input: cell to split |
nsplt | input: number of times to split the cell |
cellFaces | input: locations of original left edge, new interior faces, and right edge |
Definition at line 971 of file meshManager.cc.
void meshManager::splitCellWithZero | ( | ) |
** Create cell with r=0 at its center
Definition at line 1541 of file meshManager.cc.
|
private |
|
private |
Used for selective mesh adaptation after a sufficient time. Write the current value of time into the cells of lastDA that overlap or are contained in the mesh adaption interval. If cLastDA is one of those cells, scan the lastDA array to find the smallest time value in the array. Set tLastDA equal to that smallest time value and set cLastDA equal to the index of the cell containing that smallest value.
time | input: current time. |
tLastDA | input/output: time of last diffusion advancement. |
cLastDA | input/output: cell index. |
iStart | input: starting cell index to check. |
iEnd | input: ending cell index to check. |
Definition at line 1205 of file meshManager.cc.
domain* meshManager::domn |
pointer to odt domain to adapt
Definition at line 37 of file meshManager.h.
vector<double> meshManager::dx |
vector of cell sizes
Definition at line 41 of file meshManager.h.
int meshManager::iLower |
region of grid to adapt (the cell w/ left eddy edge)
Definition at line 52 of file meshManager.h.
int meshManager::iUpper |
region of grid to adapt (the cell w/ right eddy edge)
Definition at line 53 of file meshManager.h.
vector<double> meshManager::lastDA |
constant (unif) mesh to list time of last adapt
Definition at line 57 of file meshManager.h.
vector<int> meshManager::mark |
dummy small cell index array for sorting
Definition at line 42 of file meshManager.h.
int meshManager::ngrd |
local number of grid points
Definition at line 49 of file meshManager.h.
int meshManager::ngrdf |
local number of grid faces
Definition at line 50 of file meshManager.h.
vector<dv*> meshManager::phi |
vector of pointers to domainvariable objects
Definition at line 39 of file meshManager.h.
double meshManager::posLower |
physical region of eddy (lower bound)
Definition at line 54 of file meshManager.h.
double meshManager::posUpper |
physical region of eddy (upper bound)
Definition at line 55 of file meshManager.h.
vector<double> meshManager::X |
vector of cell center positions
Definition at line 47 of file meshManager.h.
vector<double> meshManager::xf |
vector of cell face positions
Definition at line 44 of file meshManager.h.
vector<double> meshManager::xnf |
vector of new cell face positions
Definition at line 46 of file meshManager.h.
vector<vector<double> > meshManager::yf |
vector of cell values
Definition at line 45 of file meshManager.h.