void INSStaggeredCenteredConvectiveOperator::applyConvectiveOperator(const int U_idx, const int N_idx) { IBAMR_TIMER_START(t_apply_convective_operator); #if !defined(NDEBUG) if (!d_is_initialized) { TBOX_ERROR( "INSStaggeredCenteredConvectiveOperator::applyConvectiveOperator():\n" << " operator must be initialized prior to call to applyConvectiveOperator\n"); } TBOX_ASSERT(U_idx == d_u_idx); #endif // Fill ghost cell values for all components. static const bool homogeneous_bc = false; typedef HierarchyGhostCellInterpolation::InterpolationTransactionComponent InterpolationTransactionComponent; std::vector<InterpolationTransactionComponent> transaction_comps(1); transaction_comps[0] = InterpolationTransactionComponent(d_U_scratch_idx, U_idx, "CONSERVATIVE_LINEAR_REFINE", false, "CONSERVATIVE_COARSEN", d_bdry_extrap_type, false, d_bc_coefs); d_hier_bdry_fill->resetTransactionComponents(transaction_comps); d_hier_bdry_fill->setHomogeneousBc(homogeneous_bc); StaggeredStokesPhysicalBoundaryHelper::setupBcCoefObjects( d_bc_coefs, NULL, d_U_scratch_idx, -1, homogeneous_bc); d_hier_bdry_fill->fillData(d_solution_time); StaggeredStokesPhysicalBoundaryHelper::resetBcCoefObjects(d_bc_coefs, NULL); // d_bc_helper->enforceDivergenceFreeConditionAtBoundary(d_U_scratch_idx); d_hier_bdry_fill->resetTransactionComponents(d_transaction_comps); // Compute the convective derivative. for (int ln = d_coarsest_ln; ln <= d_finest_ln; ++ln) { Pointer<PatchLevel<NDIM> > level = d_hierarchy->getPatchLevel(ln); for (PatchLevel<NDIM>::Iterator p(level); p; p++) { Pointer<Patch<NDIM> > patch = level->getPatch(p()); const Pointer<CartesianPatchGeometry<NDIM> > patch_geom = patch->getPatchGeometry(); const double* const dx = patch_geom->getDx(); const Box<NDIM>& patch_box = patch->getBox(); const IntVector<NDIM>& patch_lower = patch_box.lower(); const IntVector<NDIM>& patch_upper = patch_box.upper(); Pointer<SideData<NDIM, double> > N_data = patch->getPatchData(N_idx); Pointer<SideData<NDIM, double> > U_data = patch->getPatchData(d_U_scratch_idx); const IntVector<NDIM>& N_data_gcw = N_data->getGhostCellWidth(); const IntVector<NDIM>& U_data_gcw = U_data->getGhostCellWidth(); switch (d_difference_form) { case CONSERVATIVE: NAVIER_STOKES_STAGGERED_DIV_DERIVATIVE_FC(dx, #if (NDIM == 2) patch_lower(0), patch_upper(0), patch_lower(1), patch_upper(1), U_data_gcw(0), U_data_gcw(1), U_data->getPointer(0), U_data->getPointer(1), N_data_gcw(0), N_data_gcw(1), N_data->getPointer(0), N_data->getPointer(1) #endif #if (NDIM == 3) patch_lower(0), patch_upper(0), patch_lower(1), patch_upper(1), patch_lower(2), patch_upper(2), U_data_gcw(0), U_data_gcw(1), U_data_gcw(2), U_data->getPointer(0), U_data->getPointer(1), U_data->getPointer(2), N_data_gcw(0), N_data_gcw(1), N_data_gcw(2), N_data->getPointer(0), N_data->getPointer(1), N_data->getPointer(2) #endif ); break; case ADVECTIVE: NAVIER_STOKES_STAGGERED_ADV_DERIVATIVE_FC(dx, #if (NDIM == 2) patch_lower(0), patch_upper(0), patch_lower(1), patch_upper(1), U_data_gcw(0), U_data_gcw(1), U_data->getPointer(0), U_data->getPointer(1), N_data_gcw(0), N_data_gcw(1), N_data->getPointer(0), N_data->getPointer(1) #endif #if (NDIM == 3) patch_lower(0), patch_upper(0), patch_lower(1), patch_upper(1), patch_lower(2), patch_upper(2), U_data_gcw(0), U_data_gcw(1), U_data_gcw(2), U_data->getPointer(0), U_data->getPointer(1), U_data->getPointer(2), N_data_gcw(0), N_data_gcw(1), N_data_gcw(2), N_data->getPointer(0), N_data->getPointer(1), N_data->getPointer(2) #endif ); break; case SKEW_SYMMETRIC: NAVIER_STOKES_STAGGERED_SKEW_SYM_DERIVATIVE_FC(dx, #if (NDIM == 2) patch_lower(0), patch_upper(0), patch_lower(1), patch_upper(1), U_data_gcw(0), U_data_gcw(1), U_data->getPointer(0), U_data->getPointer(1), N_data_gcw(0), N_data_gcw(1), N_data->getPointer(0), N_data->getPointer(1) #endif #if (NDIM == 3) patch_lower(0), patch_upper(0), patch_lower(1), patch_upper(1), patch_lower(2), patch_upper(2), U_data_gcw(0), U_data_gcw(1), U_data_gcw(2), U_data->getPointer(0), U_data->getPointer(1), U_data->getPointer(2), N_data_gcw(0), N_data_gcw(1), N_data_gcw(2), N_data->getPointer(0), N_data->getPointer(1), N_data->getPointer(2) #endif ); break; default: TBOX_ERROR( "INSStaggeredCenteredConvectiveOperator::applyConvectiveOperator():\n" << " unsupported differencing form: " << enum_to_string<ConvectiveDifferencingType>(d_difference_form) << " \n" << " valid choices are: ADVECTIVE, CONSERVATIVE, SKEW_SYMMETRIC\n"); } } } IBAMR_TIMER_STOP(t_apply_convective_operator); return; } // applyConvectiveOperator
void StaggeredStokesOperator::apply(SAMRAIVectorReal<NDIM, double>& x, SAMRAIVectorReal<NDIM, double>& y) { IBAMR_TIMER_START(t_apply); // Get the vector components. const int U_idx = x.getComponentDescriptorIndex(0); const int P_idx = x.getComponentDescriptorIndex(1); const int A_U_idx = y.getComponentDescriptorIndex(0); const int A_P_idx = y.getComponentDescriptorIndex(1); const int U_scratch_idx = d_x->getComponentDescriptorIndex(0); Pointer<SideVariable<NDIM, double> > U_sc_var = x.getComponentVariable(0); Pointer<CellVariable<NDIM, double> > P_cc_var = x.getComponentVariable(1); Pointer<SideVariable<NDIM, double> > A_U_sc_var = y.getComponentVariable(0); Pointer<CellVariable<NDIM, double> > A_P_cc_var = y.getComponentVariable(1); // Simultaneously fill ghost cell values for all components. typedef HierarchyGhostCellInterpolation::InterpolationTransactionComponent InterpolationTransactionComponent; std::vector<InterpolationTransactionComponent> transaction_comps(2); transaction_comps[0] = InterpolationTransactionComponent(U_scratch_idx, U_idx, DATA_REFINE_TYPE, USE_CF_INTERPOLATION, DATA_COARSEN_TYPE, BDRY_EXTRAP_TYPE, CONSISTENT_TYPE_2_BDRY, d_U_bc_coefs, d_U_fill_pattern); transaction_comps[1] = InterpolationTransactionComponent(P_idx, DATA_REFINE_TYPE, USE_CF_INTERPOLATION, DATA_COARSEN_TYPE, BDRY_EXTRAP_TYPE, CONSISTENT_TYPE_2_BDRY, d_P_bc_coef, d_P_fill_pattern); d_hier_bdry_fill->resetTransactionComponents(transaction_comps); d_hier_bdry_fill->setHomogeneousBc(d_homogeneous_bc); StaggeredStokesPhysicalBoundaryHelper::setupBcCoefObjects( d_U_bc_coefs, d_P_bc_coef, U_scratch_idx, P_idx, d_homogeneous_bc); d_hier_bdry_fill->fillData(d_solution_time); StaggeredStokesPhysicalBoundaryHelper::resetBcCoefObjects(d_U_bc_coefs, d_P_bc_coef); // d_bc_helper->enforceDivergenceFreeConditionAtBoundary(U_scratch_idx); d_hier_bdry_fill->resetTransactionComponents(d_transaction_comps); // Compute the action of the operator: // // A*[U;P] := [A_U;A_P] = [(C*I+D*L)*U + Grad P; -Div U] d_hier_math_ops->grad(A_U_idx, A_U_sc_var, /*cf_bdry_synch*/ false, 1.0, P_idx, P_cc_var, d_no_fill, d_new_time); d_hier_math_ops->laplace(A_U_idx, A_U_sc_var, d_U_problem_coefs, U_scratch_idx, U_sc_var, d_no_fill, d_new_time, 1.0, A_U_idx, A_U_sc_var); d_hier_math_ops->div(A_P_idx, A_P_cc_var, -1.0, U_scratch_idx, U_sc_var, d_no_fill, d_new_time, /*cf_bdry_synch*/ true); d_bc_helper->copyDataAtDirichletBoundaries(A_U_idx, U_scratch_idx); IBAMR_TIMER_STOP(t_apply); return; } // apply
void INSStaggeredUpwindConvectiveOperator::applyConvectiveOperator(const int U_idx, const int N_idx) { IBAMR_TIMER_START(t_apply_convective_operator); #if !defined(NDEBUG) if (!d_is_initialized) { TBOX_ERROR("INSStaggeredUpwindConvectiveOperator::applyConvectiveOperator():\n" << " operator must be initialized prior to call to applyConvectiveOperator\n"); } TBOX_ASSERT(U_idx == d_u_idx); #endif // Allocate scratch data. for (int ln = d_coarsest_ln; ln <= d_finest_ln; ++ln) { Pointer<PatchLevel<NDIM> > level = d_hierarchy->getPatchLevel(ln); level->allocatePatchData(d_U_scratch_idx); } // Fill ghost cell values for all components. static const bool homogeneous_bc = false; typedef HierarchyGhostCellInterpolation::InterpolationTransactionComponent InterpolationTransactionComponent; std::vector<InterpolationTransactionComponent> transaction_comps(1); transaction_comps[0] = InterpolationTransactionComponent(d_U_scratch_idx, U_idx, "CONSTANT_REFINE", false, "CONSERVATIVE_COARSEN", d_bdry_extrap_type, false, d_bc_coefs); d_hier_bdry_fill->resetTransactionComponents(transaction_comps); d_hier_bdry_fill->setHomogeneousBc(homogeneous_bc); StaggeredStokesPhysicalBoundaryHelper::setupBcCoefObjects(d_bc_coefs, NULL, d_U_scratch_idx, -1, homogeneous_bc); d_hier_bdry_fill->fillData(d_solution_time); StaggeredStokesPhysicalBoundaryHelper::resetBcCoefObjects(d_bc_coefs, NULL); d_hier_bdry_fill->resetTransactionComponents(d_transaction_comps); // Compute the convective derivative. for (int ln = d_coarsest_ln; ln <= d_finest_ln; ++ln) { Pointer<PatchLevel<NDIM> > level = d_hierarchy->getPatchLevel(ln); for (PatchLevel<NDIM>::Iterator p(level); p; p++) { Pointer<Patch<NDIM> > patch = level->getPatch(p()); const Pointer<CartesianPatchGeometry<NDIM> > patch_geom = patch->getPatchGeometry(); const double* const dx = patch_geom->getDx(); const Box<NDIM>& patch_box = patch->getBox(); const IntVector<NDIM>& patch_lower = patch_box.lower(); const IntVector<NDIM>& patch_upper = patch_box.upper(); Pointer<SideData<NDIM, double> > N_data = patch->getPatchData(N_idx); Pointer<SideData<NDIM, double> > U_data = patch->getPatchData(d_U_scratch_idx); const IntVector<NDIM> ghosts = IntVector<NDIM>(1); boost::array<Box<NDIM>, NDIM> side_boxes; boost::array<Pointer<FaceData<NDIM, double> >, NDIM> U_adv_data; boost::array<Pointer<FaceData<NDIM, double> >, NDIM> U_half_data; for (unsigned int axis = 0; axis < NDIM; ++axis) { side_boxes[axis] = SideGeometry<NDIM>::toSideBox(patch_box, axis); U_adv_data[axis] = new FaceData<NDIM, double>(side_boxes[axis], 1, ghosts); U_half_data[axis] = new FaceData<NDIM, double>(side_boxes[axis], 1, ghosts); } #if (NDIM == 2) NAVIER_STOKES_INTERP_COMPS_FC(patch_lower(0), patch_upper(0), patch_lower(1), patch_upper(1), U_data->getGhostCellWidth()(0), U_data->getGhostCellWidth()(1), U_data->getPointer(0), U_data->getPointer(1), side_boxes[0].lower(0), side_boxes[0].upper(0), side_boxes[0].lower(1), side_boxes[0].upper(1), U_adv_data[0]->getGhostCellWidth()(0), U_adv_data[0]->getGhostCellWidth()(1), U_adv_data[0]->getPointer(0), U_adv_data[0]->getPointer(1), side_boxes[1].lower(0), side_boxes[1].upper(0), side_boxes[1].lower(1), side_boxes[1].upper(1), U_adv_data[1]->getGhostCellWidth()(0), U_adv_data[1]->getGhostCellWidth()(1), U_adv_data[1]->getPointer(0), U_adv_data[1]->getPointer(1)); #endif #if (NDIM == 3) NAVIER_STOKES_INTERP_COMPS_FC(patch_lower(0), patch_upper(0), patch_lower(1), patch_upper(1), patch_lower(2), patch_upper(2), U_data->getGhostCellWidth()(0), U_data->getGhostCellWidth()(1), U_data->getGhostCellWidth()(2), U_data->getPointer(0), U_data->getPointer(1), U_data->getPointer(2), side_boxes[0].lower(0), side_boxes[0].upper(0), side_boxes[0].lower(1), side_boxes[0].upper(1), side_boxes[0].lower(2), side_boxes[0].upper(2), U_adv_data[0]->getGhostCellWidth()(0), U_adv_data[0]->getGhostCellWidth()(1), U_adv_data[0]->getGhostCellWidth()(2), U_adv_data[0]->getPointer(0), U_adv_data[0]->getPointer(1), U_adv_data[0]->getPointer(2), side_boxes[1].lower(0), side_boxes[1].upper(0), side_boxes[1].lower(1), side_boxes[1].upper(1), side_boxes[1].lower(2), side_boxes[1].upper(2), U_adv_data[1]->getGhostCellWidth()(0), U_adv_data[1]->getGhostCellWidth()(1), U_adv_data[1]->getGhostCellWidth()(2), U_adv_data[1]->getPointer(0), U_adv_data[1]->getPointer(1), U_adv_data[1]->getPointer(2), side_boxes[2].lower(0), side_boxes[2].upper(0), side_boxes[2].lower(1), side_boxes[2].upper(1), side_boxes[2].lower(2), side_boxes[2].upper(2), U_adv_data[2]->getGhostCellWidth()(0), U_adv_data[2]->getGhostCellWidth()(1), U_adv_data[2]->getGhostCellWidth()(2), U_adv_data[2]->getPointer(0), U_adv_data[2]->getPointer(1), U_adv_data[2]->getPointer(2)); #endif for (unsigned int axis = 0; axis < NDIM; ++axis) { const ArrayData<NDIM, double>& U_array_data = U_data->getArrayData(axis); for (unsigned int d = 0; d < NDIM; ++d) { for (FaceIterator<NDIM> ic(side_boxes[axis], d); ic; ic++) { const FaceIndex<NDIM>& i = ic(); const double u_ADV = (*U_adv_data[axis])(i); const double U_lower = U_array_data(i.toCell(0), 0); const double U_upper = U_array_data(i.toCell(1), 0); (*U_half_data[axis])(i) = (u_ADV > 1.0e-8) ? U_lower : (u_ADV < 1.0e-8) ? U_upper : 0.5 * (U_lower + U_upper); } } } for (unsigned int axis = 0; axis < NDIM; ++axis) { switch (d_difference_form) { case CONSERVATIVE: #if (NDIM == 2) CONVECT_DERIVATIVE_FC(dx, side_boxes[axis].lower(0), side_boxes[axis].upper(0), side_boxes[axis].lower(1), side_boxes[axis].upper(1), U_adv_data[axis]->getGhostCellWidth()(0), U_adv_data[axis]->getGhostCellWidth()(1), U_half_data[axis]->getGhostCellWidth()(0), U_half_data[axis]->getGhostCellWidth()(1), U_adv_data[axis]->getPointer(0), U_adv_data[axis]->getPointer(1), U_half_data[axis]->getPointer(0), U_half_data[axis]->getPointer(1), N_data->getGhostCellWidth()(0), N_data->getGhostCellWidth()(1), N_data->getPointer(axis)); #endif #if (NDIM == 3) CONVECT_DERIVATIVE_FC(dx, side_boxes[axis].lower(0), side_boxes[axis].upper(0), side_boxes[axis].lower(1), side_boxes[axis].upper(1), side_boxes[axis].lower(2), side_boxes[axis].upper(2), U_adv_data[axis]->getGhostCellWidth()(0), U_adv_data[axis]->getGhostCellWidth()(1), U_adv_data[axis]->getGhostCellWidth()(2), U_half_data[axis]->getGhostCellWidth()(0), U_half_data[axis]->getGhostCellWidth()(1), U_half_data[axis]->getGhostCellWidth()(2), U_adv_data[axis]->getPointer(0), U_adv_data[axis]->getPointer(1), U_adv_data[axis]->getPointer(2), U_half_data[axis]->getPointer(0), U_half_data[axis]->getPointer(1), U_half_data[axis]->getPointer(2), N_data->getGhostCellWidth()(0), N_data->getGhostCellWidth()(1), N_data->getGhostCellWidth()(2), N_data->getPointer(axis)); #endif break; case ADVECTIVE: #if (NDIM == 2) ADVECT_DERIVATIVE_FC(dx, side_boxes[axis].lower(0), side_boxes[axis].upper(0), side_boxes[axis].lower(1), side_boxes[axis].upper(1), U_adv_data[axis]->getGhostCellWidth()(0), U_adv_data[axis]->getGhostCellWidth()(1), U_half_data[axis]->getGhostCellWidth()(0), U_half_data[axis]->getGhostCellWidth()(1), U_adv_data[axis]->getPointer(0), U_adv_data[axis]->getPointer(1), U_half_data[axis]->getPointer(0), U_half_data[axis]->getPointer(1), N_data->getGhostCellWidth()(0), N_data->getGhostCellWidth()(1), N_data->getPointer(axis)); #endif #if (NDIM == 3) ADVECT_DERIVATIVE_FC(dx, side_boxes[axis].lower(0), side_boxes[axis].upper(0), side_boxes[axis].lower(1), side_boxes[axis].upper(1), side_boxes[axis].lower(2), side_boxes[axis].upper(2), U_adv_data[axis]->getGhostCellWidth()(0), U_adv_data[axis]->getGhostCellWidth()(1), U_adv_data[axis]->getGhostCellWidth()(2), U_half_data[axis]->getGhostCellWidth()(0), U_half_data[axis]->getGhostCellWidth()(1), U_half_data[axis]->getGhostCellWidth()(2), U_adv_data[axis]->getPointer(0), U_adv_data[axis]->getPointer(1), U_adv_data[axis]->getPointer(2), U_half_data[axis]->getPointer(0), U_half_data[axis]->getPointer(1), U_half_data[axis]->getPointer(2), N_data->getGhostCellWidth()(0), N_data->getGhostCellWidth()(1), N_data->getGhostCellWidth()(2), N_data->getPointer(axis)); #endif break; case SKEW_SYMMETRIC: #if (NDIM == 2) SKEW_SYM_DERIVATIVE_FC(dx, side_boxes[axis].lower(0), side_boxes[axis].upper(0), side_boxes[axis].lower(1), side_boxes[axis].upper(1), U_adv_data[axis]->getGhostCellWidth()(0), U_adv_data[axis]->getGhostCellWidth()(1), U_half_data[axis]->getGhostCellWidth()(0), U_half_data[axis]->getGhostCellWidth()(1), U_adv_data[axis]->getPointer(0), U_adv_data[axis]->getPointer(1), U_half_data[axis]->getPointer(0), U_half_data[axis]->getPointer(1), N_data->getGhostCellWidth()(0), N_data->getGhostCellWidth()(1), N_data->getPointer(axis)); #endif #if (NDIM == 3) SKEW_SYM_DERIVATIVE_FC(dx, side_boxes[axis].lower(0), side_boxes[axis].upper(0), side_boxes[axis].lower(1), side_boxes[axis].upper(1), side_boxes[axis].lower(2), side_boxes[axis].upper(2), U_adv_data[axis]->getGhostCellWidth()(0), U_adv_data[axis]->getGhostCellWidth()(1), U_adv_data[axis]->getGhostCellWidth()(2), U_half_data[axis]->getGhostCellWidth()(0), U_half_data[axis]->getGhostCellWidth()(1), U_half_data[axis]->getGhostCellWidth()(2), U_adv_data[axis]->getPointer(0), U_adv_data[axis]->getPointer(1), U_adv_data[axis]->getPointer(2), U_half_data[axis]->getPointer(0), U_half_data[axis]->getPointer(1), U_half_data[axis]->getPointer(2), N_data->getGhostCellWidth()(0), N_data->getGhostCellWidth()(1), N_data->getGhostCellWidth()(2), N_data->getPointer(axis)); #endif break; default: TBOX_ERROR("INSStaggeredUpwindConvectiveOperator::applyConvectiveOperator():\n" << " unsupported differencing form: " << enum_to_string<ConvectiveDifferencingType>(d_difference_form) << " \n" << " valid choices are: ADVECTIVE, CONSERVATIVE, SKEW_SYMMETRIC\n"); } } } } // Deallocate scratch data. for (int ln = d_coarsest_ln; ln <= d_finest_ln; ++ln) { Pointer<PatchLevel<NDIM> > level = d_hierarchy->getPatchLevel(ln); level->deallocatePatchData(d_U_scratch_idx); } IBAMR_TIMER_STOP(t_apply_convective_operator); return; } // applyConvectiveOperator