Exemplo n.º 1
0
inline double
compute_linear_extrap(
    D& patch_data,
    const I& i,
    const I& i_intr,
    const IntVector<NDIM>& i_shft,
    const int depth)
{
    double ret_val = patch_data(i_intr,depth);
    for (unsigned int d = 0; d < NDIM; ++d)
    {
        if (i_shft(d) != 0)
        {
            const I& i_intr0 = i_intr;
            I i_intr1 = i_intr;
            i_intr1(d) += i_shft(d);

            const double& f0 = patch_data(i_intr0,depth);
            const double& f1 = patch_data(i_intr1,depth);

            const double du = f0-f1;
            const double delta = std::abs(i(d)-i_intr(d));

            ret_val += du*delta;
        }
    }
    return ret_val;
}// compute_linear_extrap
Exemplo n.º 2
0
inline double
compute_quadratic_extrap(D& patch_data,
                         const I& i,
                         const I& i_intr,
                         const IntVector<NDIM>& i_shft,
                         const int depth,
                         const int codim)
{
    if (codim == 1)
    {
        for (unsigned int d = 0; d < NDIM; ++d)
        {
            if (i_shft(d) != 0)
            {
                const I& i_intr0 = i_intr;

                I i_intr1 = i_intr;
                i_intr1(d) += i_shft(d);

                I i_intr2 = i_intr1;
                i_intr2(d) += i_shft(d);

                const double& f0 = patch_data(i_intr0, depth);
                const double& f1 = patch_data(i_intr1, depth);
                const double& f2 = patch_data(i_intr2, depth);

                const double x = std::abs(i(d) - i_intr(d));

                return (1.0 / 2.0 * f2 - f1 + 1.0 / 2.0 * f0) * x * x +
                       (-1.0 / 2.0 * f2 + 2.0 * f1 - 3.0 / 2.0 * f0) * x + f0;
            }
        }
    }
    else
    {
        return compute_linear_extrap(patch_data, i, i_intr, i_shft, depth);
    }
    return 0.0; // this statement should not be reached
} // compute_quadratic_extrap
Exemplo n.º 3
0
inline double
compute_quadratic_extrap(
    D& patch_data,
    const I& i,
    const I& i_intr,
    const IntVector<NDIM>& i_shft,
    const int depth,
    const int codim)
{
    if (codim == 1)
    {
        for (unsigned int d = 0; d < NDIM; ++d)
        {
            if (i_shft(d) != 0)
            {
#if 1
                const I& i_intr0 = i_intr;

                I i_intr1 = i_intr;
                i_intr1(d) += i_shft(d);

                I i_intr2 = i_intr1;
                i_intr2(d) += i_shft(d);

                const double& f0 = patch_data(i_intr0,depth);
                const double& f1 = patch_data(i_intr1,depth);
                const double& f2 = patch_data(i_intr2,depth);

                const double x = std::abs(i(d)-i_intr(d));

                return (1.0/2.0*f2-f1+1.0/2.0*f0)*x*x+(-1.0/2.0*f2+2.0*f1-3.0/2.0*f0)*x+f0;
#endif

#if 0
                // NOTE: The following only works in general for the case that
                // the ghost cell width is >= 3.
                const I& i_intr0 = i_intr;

                I i_intr2 = i_intr;
                i_intr2(d) += 2*i_shft(d);

                I i_intr3 = i_intr2;
                i_intr3(d) += i_shft(d);

                const double& f0 = patch_data(i_intr0,depth);
                const double& f2 = patch_data(i_intr2,depth);
                const double& f3 = patch_data(i_intr3,depth);

                const double x = std::abs(i(d)-i_intr(d));

                return (1.0/3.0*f3-1.0/2.0*f2+1.0/6.0*f0)*x*x+(-2.0/3.0*f3+3.0/2.0*f2-5.0/6.0*f0)*x+f0;
#endif
            }
        }
    }
    else
    {
        return compute_linear_extrap(patch_data, i, i_intr, i_shft, depth);
    }
    return 0.0; // this statement should not be reached
}// compute_quadratic_extrap
void
AdvDiffPhysicalBoundaryUtilities::setPhysicalBoundaryConditions(
    Pointer<CellData<NDIM,double> > Q_data,
    Pointer<FaceData<NDIM,double> > u_ADV_data,
    Pointer<Patch<NDIM> > patch,
    const std::vector<RobinBcCoefStrategy<NDIM>*>& bc_coefs,
    const double fill_time,
    const bool inflow_boundaries_only,
    const bool homogeneous_bc)
{
    Pointer<CartesianPatchGeometry<NDIM> > pgeom = patch->getPatchGeometry();
    if (!pgeom->getTouchesRegularBoundary()) return;
    const Array<BoundaryBox<NDIM> > physical_codim1_boxes = PhysicalBoundaryUtilities::getPhysicalBoundaryCodim1Boxes(*patch);
    if (physical_codim1_boxes.size() == 0) return;

    // Loop over the boundary fill boxes and set boundary conditions.
    const Box<NDIM>& patch_box = patch->getBox();
    const double* const dx = pgeom->getDx();

    // Setup any extended Robin BC coef objects.
    for (int depth = 0; depth < Q_data->getDepth(); ++depth)
    {
        ExtendedRobinBcCoefStrategy* extended_bc_coef = dynamic_cast<ExtendedRobinBcCoefStrategy*>(bc_coefs[depth]);
        if (extended_bc_coef)
        {
            extended_bc_coef->clearTargetPatchDataIndex();
            extended_bc_coef->setHomogeneousBc(homogeneous_bc);
        }
    }

    // Set the boundary conditions.
    const IntVector<NDIM>& gcw = Q_data->getGhostCellWidth();
    for (int n = 0; n < physical_codim1_boxes.size(); ++n)
    {
        const BoundaryBox<NDIM>& bdry_box   = physical_codim1_boxes[n];
        const unsigned int location_index   = bdry_box.getLocationIndex();
        const unsigned int bdry_normal_axis = location_index/2;
        const bool is_lower                 = location_index%2 == 0;
        static const IntVector<NDIM> gcw_to_fill = 1;
        const Box<NDIM> bc_fill_box = pgeom->getBoundaryFillBox(bdry_box, patch_box, gcw_to_fill);
        const BoundaryBox<NDIM> trimmed_bdry_box(bdry_box.getBox() * bc_fill_box, bdry_box.getBoundaryType(), bdry_box.getLocationIndex());
        Box<NDIM> bc_coef_box = PhysicalBoundaryUtilities::makeSideBoundaryCodim1Box(trimmed_bdry_box);
        for (unsigned int d = 0; d < NDIM; ++d)
        {
            if (d != bdry_normal_axis)
            {
                bc_coef_box.lower(d) = std::max(bc_coef_box.lower(d), patch_box.lower(d));
                bc_coef_box.upper(d) = std::min(bc_coef_box.upper(d), patch_box.upper(d));
            }
        }
        Pointer<ArrayData<NDIM,double> > acoef_data = new ArrayData<NDIM,double>(bc_coef_box, 1);
        Pointer<ArrayData<NDIM,double> > bcoef_data = new ArrayData<NDIM,double>(bc_coef_box, 1);
        Pointer<ArrayData<NDIM,double> > gcoef_data = new ArrayData<NDIM,double>(bc_coef_box, 1);
        for (int depth = 0; depth < Q_data->getDepth(); ++depth)
        {
            bc_coefs[depth]->setBcCoefs(acoef_data, bcoef_data, gcoef_data, NULL, *patch, trimmed_bdry_box, fill_time);
            ExtendedRobinBcCoefStrategy* extended_bc_coef = dynamic_cast<ExtendedRobinBcCoefStrategy*>(bc_coefs[depth]);
            if (homogeneous_bc && !extended_bc_coef) gcoef_data->fillAll(0.0);
            for (Box<NDIM>::Iterator bc(bc_coef_box); bc; bc++)
            {
                const Index<NDIM>& i = bc();
                const FaceIndex<NDIM> i_f(i, bdry_normal_axis, FaceIndex<NDIM>::Lower);
                bool is_inflow_bdry = (is_lower && (*u_ADV_data)(i_f) > 0.0) || (!is_lower && (*u_ADV_data)(i_f) < 0.0);
                if (!inflow_boundaries_only || is_inflow_bdry)
                {
                    const double& a = (*acoef_data)(i,0);
                    const double& b = (*bcoef_data)(i,0);
                    const double& g = (*gcoef_data)(i,0);
                    const double& h = dx[bdry_normal_axis];
                    int sgn;
                    Index<NDIM> i_intr(i);
                    if (is_lower)
                    {
                        sgn = -1;
                    }
                    else
                    {
                        sgn = +1;
                        i_intr(bdry_normal_axis) -= 1;
                    }
                    Index<NDIM> i_true(i_intr), i_ghost(i_intr);
                    for (int k = 1; k <= gcw(bdry_normal_axis); ++k)
                    {
                        i_ghost(bdry_normal_axis) = i_intr(bdry_normal_axis) + sgn*k;
                        i_true (bdry_normal_axis) = i_intr(bdry_normal_axis) - sgn*(k-1);
                        const double Q_i = (*Q_data)(i_true,depth);
                        (*Q_data)(i_ghost,depth) = -(-4.0*g*h*k-2.0*g*h+2.0*a*Q_i*h*k+a*Q_i*h-2.0*b*Q_i)/(2.0*a*h*k+a*h+2.0*b);
                    }
                }
            }
        }
    }
    return;
}// setPhysicalBoundaryConditions