Scheme<double> Cell::phi(vector<shared_ptr<Boundary> > const &bc, int_2 bias) { Scheme<double> sch; if (next < 0 && prev < 0) { sch.push_pair(id, 1.0); } else { // use next and prev to compute phi; if (next >= 0 && prev >= 0) { if (bias == 0) { double dn = abs((grid->listCell[next]->getCoord() - getCoord())*vol()); double dp = abs((grid->listCell[prev]->getCoord() - getCoord())*vol()); sch.push_pair(prev, dn/(dn+dp)); sch.push_pair(next, dp/(dn+dp)); } else if (bias == -1) { sch.push_pair(prev, 1.0); } else if (bias == 1) { sch.push_pair(next, 1.0); } } else { auto bndr = (prev >= 0) ? -next-1 : -prev-1; auto row = (prev >= 0) ? prev : next; if (bc[bndr]->type == 0) { sch.push_constant(bc[bndr]->b_val); sch.push_pair(row, bc[bndr]->a_val); } else if (bc[bndr]->type == 1) { auto c0 = grid->listCell[row]; auto norm = vol(); norm = norm/norm.abs(); double dx = norm*(getCoord() - c0->getCoord()); sch.push_constant(dx*bc[bndr]->b_val); sch.push_pair(row, (1.0 + dx*bc[bndr]->a_val)); } else { cout << "Cell (Quad) :: interp :: boundary condition type not recognized " << endl; exit(1); } } } return sch; }
Scheme<double> Cell::normGrad(vector<shared_ptr<Boundary> > const &bc) { Scheme<double> sch; if (next < 0 && prev < 0) { // control volume of the cell; cout << "You can only call form normGrad for a face!!! " << endl; exit(1); } else { // use next and prev to compute phi; if (next >= 0 && prev >= 0) { if (grid->listCell[next]->level[orient] == grid->listCell[prev]->level[orient]) { auto norm = vol(); auto area = norm.abs(); norm = norm/area; auto dx = grid->listCell[next]->getCoord() - grid->listCell[prev]->getCoord(); auto onebydx = 1.0/(dx*norm); sch.push_pair(next, onebydx); sch.push_pair(prev, -onebydx); } else { // this part is cell specific // 2d-3d vector<Vec3> v; vector<Scheme<double>> tmp; auto norm = vol(); norm = norm/norm.abs(); v.push_back(grid->listCell[prev]->getCoord()); v.push_back(*(grid->listVertex[node[0]])); v.push_back(grid->listCell[next]->getCoord()); v.push_back(*(grid->listVertex[node[1]])); tmp.push_back(grid->listCell[prev]->phi(bc)); tmp.push_back(grid->listVertex[node[0]]->phi(bc)); tmp.push_back(grid->listCell[next]->phi(bc)); tmp.push_back(grid->listVertex[node[1]]->phi(bc)); tmp[3] += grid->listCell[prev]->phi(bc); tmp[0] += grid->listVertex[node[0]]->phi(bc); tmp[1] += grid->listCell[next]->phi(bc); tmp[2] += grid->listVertex[node[1]]->phi(bc); auto vol = 0.5*((v[3]-v[1])^(v[2]-v[0])).abs(); for (auto j = 0; j < 4; ++j) { auto del = v[(j+1)%4] - v[j]; auto area = Vec3(-del[1], del[0], 0); for (auto i = 0; i < tmp[j].size(); ++i) sch.push_pair(tmp[j].ind[i], (0.5*tmp[j].val[i]/vol)*area*norm); //0.5 from average; } } } else { // cout << "**** " << vol() << " " << type << endl; // cout << *(grid->listVertex[node[0]]) << " " << *(grid->listVertex[node[1]]) << endl; auto bndr = (prev >= 0) ? -next-1 : -prev-1; auto row = (prev >= 0) ? prev : next; auto norm = vol(); auto area = norm.abs(); norm = norm/area; auto dx = (next >= 0) ? grid->listCell[next]->getCoord() - getCoord() : getCoord() - grid->listCell[prev]->getCoord(); auto onebydx = 1.0/(dx*norm); if (bc[bndr]->type == 0) { if (row == next) onebydx = -onebydx; sch.push_constant(bc[bndr]->b_val * onebydx); sch.push_pair(row, (bc[bndr]->a_val - 1.0) * onebydx); } else if (bc[bndr]->type == 1) { sch.push_constant((bc[bndr]->b_val)); sch.push_pair(row, (bc[bndr]->a_val)); } else { cout << "Cell (Line) :: grad :: boundary condition type not recognized " << endl; exit(1); } } } return sch; }