int ComputeSolutionFunctional(const Time *time, Space *space, const Model *model) { FILE *filePointer = fopen("solution_functional.csv", "a"); if (NULL == filePointer) { FatalError("failed to write data..."); } if (0 == time->stepC) { /* this is the initialization step */ fprintf(filePointer, "# time, kinetic energy, enstrophy \n"); } const Partition *restrict part = &(space->part); Node *const node = space->node; Real *restrict U = NULL; /* numerical solution */ int idx = 0; /* linear array index math variable */ const RealVec d = {part->d[X], part->d[Y], part->d[Z]}; const int h[DIMS][DIMS] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; /* direction indicator */ Real rho = model->refRho; /* density */ RealVec V = {0.0}; /* velocity */ RealVec W = {0.0}; /* vorticity */ Real Vs[DIMS][NSTENCIL] = {{0.0}}; /* velocity stencil */ Real dV[DIMS][DIMS] = {{0.0}}; /* velocity gradient */ Real Ek = 0.0; /* kinetic energy */ Real Ee = 0.0; /* enstrophy */ int N = 0; /* number of nodes */ for (int k = part->ns[PIN][Z][MIN]; k < part->ns[PIN][Z][MAX]; ++k) { for (int j = part->ns[PIN][Y][MIN]; j < part->ns[PIN][Y][MAX]; ++j) { for (int i = part->ns[PIN][X][MIN]; i < part->ns[PIN][X][MAX]; ++i) { for (int s = 0; s < DIMS; ++s) { for (int n = -CEN; n <= CEN; ++n) { idx = IndexNode(k + n * h[s][Z], j + n * h[s][Y], i + n * h[s][X], part->n[Y], part->n[X]); U = node[idx].U[TO]; Vs[X][CEN+n] = U[1] / U[0]; Vs[Y][CEN+n] = U[2] / U[0]; Vs[Z][CEN+n] = U[3] / U[0]; } dV[X][s] = (-Vs[X][CEN+2] + 8.0 * Vs[X][CEN+1] - 8.0 * Vs[X][CEN-1] + Vs[X][CEN-2]) / (12.0 * d[s]); dV[Y][s] = (-Vs[Y][CEN+2] + 8.0 * Vs[Y][CEN+1] - 8.0 * Vs[Y][CEN-1] + Vs[Y][CEN-2]) / (12.0 * d[s]); dV[Z][s] = (-Vs[Z][CEN+2] + 8.0 * Vs[Z][CEN+1] - 8.0 * Vs[Z][CEN-1] + Vs[Z][CEN-2]) / (12.0 * d[s]); } idx = IndexNode(k, j, i, part->n[Y], part->n[X]); U = node[idx].U[TO]; rho = U[0]; V[X] = U[1] / U[0]; V[Y] = U[2] / U[0]; V[Z] = U[3] / U[0]; W[X] = dV[Z][Y] - dV[Y][Z]; W[Y] = dV[X][Z] - dV[Z][X]; W[Z] = dV[Y][X] - dV[X][Y]; Ek = Ek + rho * Dot(V,V); Ee = Ee + rho * Dot(W,W); ++N; } } } Ek = 0.5 * Ek / N; Ee = 0.5 * Ee / N; fprintf(filePointer, "%.6g, %.6g, %.6g\n", time->now, Ek, Ee); fclose(filePointer); /* close current opened file */ return 0; }
const SimpleNode<T>* ConstListIterator<T>::Prev() { if (!Less()) return NULL; return IndexNode(_Index - 1); }
IndexNode IndexPage::newIndex(const char* key, int pageId, size_t cursor) { syncFlag = false; size_t size = IndexNode::getSize(key); // Create from free space if (freeSpace() >= size) { IndexNode rec(*this, indexStartPos + indexSpace()); rec.init(key, pageId, cursor); setIndexCount(indexCount() + 1); setIndexSpace(indexSpace() + size); setFreeSpace(freeSpace() - size); return rec; } // Check free node list try { IndexNode rec = freeList->findIndex(size); freeList->shrinkIndex(rec, size); // Init record rec.init(key, pageId, cursor); return rec; } catch (ReachLastIndex) { error("No space for new record"); return IndexNode(*this, 0); // Aviod Warning } }
/**************************************************************************** * Function definitions ****************************************************************************/ int SetField(const int tn, Space *space, const Model *model) { const Partition *restrict part = &(space->part); Node *const node = space->node; int idx = 0; /* linear array index math variable */ /* extract global initial values */ const Real Uo[DIMUo] = { part->valueIC[0][ENTRYIC-5], part->valueIC[0][ENTRYIC-4], part->valueIC[0][ENTRYIC-3], part->valueIC[0][ENTRYIC-2], part->valueIC[0][ENTRYIC-1]}; Real Ue[DIMUo] = {0.0}; RealVec p = {0.0}; for (int k = part->ns[PIN][Z][MIN]; k < part->ns[PIN][Z][MAX]; ++k) { for (int j = part->ns[PIN][Y][MIN]; j < part->ns[PIN][Y][MAX]; ++j) { for (int i = part->ns[PIN][X][MIN]; i < part->ns[PIN][X][MAX]; ++i) { idx = IndexNode(k, j, i, part->n[Y], part->n[X]); p[X] = PointSpace(i, part->domain[X][MIN], part->d[X], part->ng); p[Y] = PointSpace(j, part->domain[Y][MIN], part->d[Y], part->ng); p[Z] = PointSpace(k, part->domain[Z][MIN], part->d[Z], part->ng); SetCase[CASE](p[X], p[Y], p[Z], model, Uo, Ue); ConservativeByPrimitive(model->gamma, Ue, node[idx].U[tn]); } } } BoundaryConditionsAndTreatments(tn, space, model); return 0; }
int ComputeSolutionError(Space *space, const Model *model) { FILE *filePointer = fopen("solution_error.csv", "w"); if (NULL == filePointer) { FatalError("failed to write data..."); } const Partition *restrict part = &(space->part); Node *const node = space->node; Real *restrict Us = NULL; /* numerical solution */ Real *restrict Ue = NULL; /* exact solution */ int idx = 0; /* linear array index math variable */ const int meshN = MaxInt(part->m[X], MaxInt(part->m[Y], part->m[Z])); Real norm[3] = {0.0}; /* Lp norms */ int N = 0; /* number of nodes */ Real err = 0.0; /* solution error */ SetField(TN, space, model); /* compute exact solution field */ for (int k = part->ns[PIN][Z][MIN]; k < part->ns[PIN][Z][MAX]; ++k) { for (int j = part->ns[PIN][Y][MIN]; j < part->ns[PIN][Y][MAX]; ++j) { for (int i = part->ns[PIN][X][MIN]; i < part->ns[PIN][X][MAX]; ++i) { idx = IndexNode(k, j, i, part->n[Y], part->n[X]); Us = node[idx].U[TO]; Ue = node[idx].U[TN]; err = fabs(Us[0] - Ue[0]); norm[0] = MaxReal(norm[0], err); norm[1] = norm[1] + err; norm[2] = norm[2] + err * err; ++N; } } } norm[1] = norm[1] / N; norm[2] = sqrt(norm[2] / N); fprintf(filePointer, "# mesh, l1 norm, l2 norm, max norm\n"); fprintf(filePointer, "%d, %.6g, %.6g, %.6g\n", meshN, norm[1], norm[2], norm[0]); fclose(filePointer); /* close current opened file */ return 0; }
IndexNode IndexPage::getIndex(size_t cursor) { return IndexNode(*this, cursor); }
static void ApplyBoundaryConditions(const int p, const int r, int box[restrict][LIMIT], const int tn, Space *space, const Model *model) { const Partition *restrict part = &(space->part); Node *const node = space->node; Real *restrict UG = NULL; Real *restrict UI = NULL; Real *restrict UO = NULL; Real *restrict Uh = NULL; int idxG = 0; /* index at ghost node */ int idxI = 0; /* index at image node */ int idxO = 0; /* index at boundary point */ int idxh = 0; /* index at neighbouring point */ const Real zero = 0.0; Real UoG[DIMUo] = {zero}; Real UoI[DIMUo] = {zero}; Real UoO[DIMUo] = {zero}; Real Uoh[DIMUo] = {zero}; const Real UoGiven[DIMUo] = { /* specified primitive values of current boundary */ part->valueBC[p][0], part->valueBC[p][1], part->valueBC[p][2], part->valueBC[p][3], part->valueBC[p][4], part->valueBC[p][5]}; const IntVec N = {part->N[p][X], part->N[p][Y], part->N[p][Z]}; const IntVec LN = {part->m[X] * N[X], part->m[Y] * N[Y], part->m[Z] * N[Z]}; for (int k = box[Z][MIN]; k < box[Z][MAX]; ++k) { for (int j = box[Y][MIN]; j < box[Y][MAX]; ++j) { for (int i = box[X][MIN]; i < box[X][MAX]; ++i) { /* * Apply boundary conditions for current node, always remember * that boundary conditions should be based on primitive * variables rather than conservative variables. */ if (0 != r) { /* treat ghost layers */ idxG = IndexNode(k, j, i, part->n[Y], part->n[X]); UG = node[idxG].U[tn]; switch (part->typeBC[p]) { case SLIPWALL: case NOSLIPWALL: idxO = IndexNode(k - r*N[Z], j - r*N[Y], i - r*N[X], part->n[Y], part->n[X]); UO = node[idxO].U[tn]; PrimitiveByConservative(model->gamma, model->gasR, UO, UoO); idxI = IndexNode(k - 2*r*N[Z], j - 2*r*N[Y], i - 2*r*N[X], part->n[Y], part->n[X]); UI = node[idxI].U[tn]; PrimitiveByConservative(model->gamma, model->gasR, UI, UoI); MethodOfImage(UoI, UoO, UoG); UoG[0] = UoG[4] / (UoG[5] * model->gasR); /* compute density */ ConservativeByPrimitive(model->gamma, UoG, UG); break; case PERIODIC: idxh = IndexNode(k - LN[Z], j - LN[Y], i - LN[X], part->n[Y], part->n[X]); Uh = node[idxh].U[tn]; ZeroGradient(Uh, UG); break; default: idxh = IndexNode(k - N[Z], j - N[Y], i - N[X], part->n[Y], part->n[X]); Uh = node[idxh].U[tn]; ZeroGradient(Uh, UG); break; } continue; } idxO = IndexNode(k, j, i, part->n[Y], part->n[X]); UO = node[idxO].U[tn]; switch (part->typeBC[p]) { /* treat physical boundary */ case INFLOW: ConservativeByPrimitive(model->gamma, UoGiven, UO); break; case OUTFLOW: /* Calculate inner neighbour nodes according to normal vector direction. */ idxh = IndexNode(k - N[Z], j - N[Y], i - N[X], part->n[Y], part->n[X]); Uh = node[idxh].U[tn]; ZeroGradient(Uh, UO); break; case SLIPWALL: /* zero-gradient for scalar and tangential component, zero for normal component */ idxh = IndexNode(k - N[Z], j - N[Y], i - N[X], part->n[Y], part->n[X]); Uh = node[idxh].U[tn]; PrimitiveByConservative(model->gamma, model->gasR, Uh, Uoh); UoO[1] = (!N[X]) * Uoh[1]; UoO[2] = (!N[Y]) * Uoh[2]; UoO[3] = (!N[Z]) * Uoh[3]; UoO[4] = Uoh[4]; /* zero normal gradient of pressure */ if (zero > UoGiven[5]) { /* adiabatic, dT/dn = 0 */ UoO[5] = Uoh[5]; } else { /* otherwise, use specified constant wall temperature, T = Tw */ UoO[5] = UoGiven[5]; } UoO[0] = UoO[4] / (UoO[5] * model->gasR); /* compute density */ ConservativeByPrimitive(model->gamma, UoO, UO); break; case NOSLIPWALL: idxh = IndexNode(k - N[Z], j - N[Y], i - N[X], part->n[Y], part->n[X]); Uh = node[idxh].U[tn]; PrimitiveByConservative(model->gamma, model->gasR, Uh, Uoh); UoO[1] = zero; UoO[2] = zero; UoO[3] = zero; UoO[4] = Uoh[4]; /* zero normal gradient of pressure */ if (zero > UoGiven[5]) { /* adiabatic, dT/dn = 0 */ UoO[5] = Uoh[5]; } else { /* otherwise, use specified constant wall temperature, T = Tw */ UoO[5] = UoGiven[5]; } UoO[0] = UoO[4] / (UoO[5] * model->gasR); /* compute density */ ConservativeByPrimitive(model->gamma, UoO, UO); break; case PERIODIC: /* no treatment needed since global boundary participate normal computation*/ break; default: break; } } } } return; }
int main() { listPtr List, Queue, Stack, Splay; char *String1, *String2, *String3, *String4, *Get; int Result; printf("Testing LINKLIST Library for ANSI C.\n\n"); String1 = malloc(20); String2 = malloc(20); String3 = malloc(20); String4 = malloc(20); strcpy(String1, "Hi"); strcpy(String2, "Low"); strcpy(String3, "Up"); strcpy(String4, "Down"); printf("Creating List.\n"); List = NewListAlloc(LIST, DMALLOC, DFREE, (NodeCompareFunc)strcmp); printf("Creating Queue.\n"); Queue = NewListAlloc(QUEUE, DMALLOC, DFREE, NULL); printf("Creating Stack.\n"); Stack = NewListAlloc(STACK, DMALLOC, DFREE, NULL); printf("Creating Splay Tree\n"); Splay = NewListAlloc(STREE, DMALLOC, DFREE, (NodeCompareFunc)StringCompare); printf("Adding Elements to List...\n"); AddNode(List, NewNode("Hi")); AddNode(List, NewNode("Low")); AddNode(List, NewNode("Up")); AddNode(List, NewNode("Down")); printf("Adding Elements to Queue...\n"); AddNode(Queue, NewNode("Hi")); AddNode(Queue, NewNode("Low")); AddNode(Queue, NewNode("Up")); AddNode(Queue, NewNode("Down")); printf("Adding Elements to Stack...\n"); AddNode(Stack, NewNode(String1)); AddNode(Stack, NewNode(String2)); AddNode(Stack, NewNode(String3)); AddNode(Stack, NewNode(String4)); printf("Adding Elements to Splay Tree...\n"); AddNode(Splay, NewNode("High")); AddNode(Splay, NewNode("Low")); AddNode(Splay, NewNode("Up")); AddNode(Splay, NewNode("Down")); printf("Attempting to add duplicate nodes to Splay Tree...\n"); Result = AddNode(Splay, NewNode("Down")); printf("Result: "); if (Result == LLIST_OK) printf("OK\n"); else if (Result == LLIST_BADVALUE) printf("Node Already Exists; not added\n"); else printf("Error\n"); printf("Calimed Memory: %d bytes\n", DCOUNT(NULL)); printf("LIST:\n"); PrintList(List, "%s"); printf("QUEUE:\n"); PrintList(Queue, "%s"); printf("STACK:\n"); PrintList(Stack, "%s"); printf("SPLAY:\n"); PrintList(Splay, "%s"); printf("\n-----------------------\n"); printf("Reading Element from LIST\n"); printf("Read Element: %s\n", GetNode(List)); PrintList(List, "%s"); printf("\n\nReading Element from QUEUE\n"); printf("Read Element: %s\n", GetNode(Queue)); PrintList(Queue, "%s"); printf("\n\nReading Element from STACK\n"); printf("Read Element: %s\n", (Get = GetNode(Stack))); DFREE(Get); PrintList(Stack, "%s"); printf("\n-----------------------\n"); printf("Reading Element #2 from LIST\n"); printf("Read Element: %s\n", IndexNode(List, 2)); PrintList(List, "%s"); printf("\nAdding One More Element to LIST\n"); AddNode(List, NewNode("And")); PrintList(List, "%s"); printf("\n-----------------------\n"); printf("\nSorting LIST\n"); SortList(List); PrintList(List, "%s"); printf("\n-----------------------\n"); printf("\nDeleting Element 2 From LIST\n"); IndexNode(List, 2); RemoveList(List); PrintList(List, "%s"); printf("\nDeleting Head From LIST\n"); DelHeadList(List); PrintList(List, "%s"); printf("\nDeleting Tail From LIST\n"); DelTailList(List); PrintList(List, "%s"); printf("\n------------------------\n"); printf("Reading Element from Splay Tree\n"); printf("Read Element: %s\n", GetNode(Splay)); printf("\nDeleting Element From Splay Tree\n"); DelNode(Splay); PrintList(Splay, "%s"); printf("\nDeleting Element \"Low\" In Splay Tree\n"); FindNode(Splay, "Low"); DelNode(Splay); PrintList(Splay, "%s"); printf("Reading Element from Splay Tree\n"); printf("Read Element: %s\n", GetNode(Splay)); printf("\n-----------------------\n"); printf("Removing List.\n"); FreeList(List, NULL); printf("Removing Queue.\n"); FreeList(Queue, NULL); printf("Removing Stack.\n"); FreeList(Stack, NULL); printf("Removing Splay Tree.\n"); FreeList(Splay, NULL); printf("\n-----------------------\n"); printf("\nUnclaimed Memory: %d bytes\n", DCOUNT(NULL)); printf("\nLinkList Test/Demo Done.\n"); return 0; } /* main */