Go to the documentation of this file.
21 #ifndef THUNDEREGG_VARPOISSON_STARPATCHOPERATOR_H
22 #define THUNDEREGG_VARPOISSON_STARPATCHOPERATOR_H
37 namespace VarPoisson {
51 constexpr
int addValue(
int axis)
const {
return (axis == 0) ? 0 : 1; }
68 throw RuntimeError(
"StarPatchOperator needs at least one set of ghost cells");
84 enforceInternalBoundaryConditions(pinfo, u_view);
86 enforceBoundaryConditions(pinfo, u_view);
89 std::array<double, D> h2 = pinfo.
spacings;
90 for (
size_t i = 0; i < D; i++) {
96 Loop::OverInteriorIndexes<D + 1>(u_view, [&](std::array<int, D + 1> coord) {
97 const double* ptr = &u_view[coord];
98 const double* c_ptr = &c[coord];
99 double lower = *(ptr - stride);
101 double upper = *(ptr + stride);
102 double c_lower = *(c_ptr - c_stride);
103 double c_mid = *c_ptr;
104 double c_upper = *(c_ptr + c_stride);
106 addValue(axis) * f_view[coord] +
107 ((c_upper + c_mid) * (upper - mid) - (c_lower + c_mid) * (mid - lower)) / (2 * h2[axis]);
116 applySinglePatch(pinfo, u_view, f_view,
false);
123 applySinglePatch(pinfo, u_view, f_view,
true);
126 void enforceBoundaryConditions(
const PatchInfo<D>& pinfo,
129 for (
int axis = 0; axis < D; axis++) {
131 Side<D> upper_side(axis * 2 + 1);
132 if (!pinfo.
hasNbr(lower_side)) {
135 Loop::OverInteriorIndexes<D>(mid,
136 [&](std::array<int, D> coord) { lower[coord] = -mid[coord]; });
138 if (!pinfo.
hasNbr(upper_side)) {
140 View<const double, D> mid = u_view.
getSliceOn(upper_side, { 0 });
141 Loop::OverInteriorIndexes<D>(mid,
142 [&](std::array<int, D> coord) { upper[coord] = -mid[coord]; });
147 void enforceInternalBoundaryConditions(
const PatchInfo<D>& pinfo,
148 const PatchView<const double, D>& u_view)
const
150 for (
int axis = 0; axis < D; axis++) {
151 Side<D> lower_side(axis * 2);
152 Side<D> upper_side(axis * 2 + 1);
153 if (pinfo.hasNbr(lower_side)) {
154 View<double, D> lower = u_view.getGhostSliceOn(lower_side, { 0 });
155 View<const double, D> mid = u_view.getSliceOn(lower_side, { 0 });
156 Loop::OverInteriorIndexes<D>(mid,
157 [&](std::array<int, D> coord) { lower[coord] = -mid[coord]; });
159 if (pinfo.hasNbr(upper_side)) {
160 View<double, D> upper = u_view.getGhostSliceOn(upper_side, { 0 });
161 View<const double, D> mid = u_view.getSliceOn(upper_side, { 0 });
162 Loop::OverInteriorIndexes<D>(mid,
163 [&](std::array<int, D> coord) { upper[coord] = -mid[coord]; });
175 double h2 = pow(pinfo.
spacings[s.getAxisIndex()], 2);
181 Loop::OverInteriorIndexes<D>(fner, [&](
const std::array<int, D>& coord) {
182 fner[coord] -= (u_ghost[coord] + uner[coord]) * (cner[coord] + c_ghost[coord]) / (2 * h2);
195 std::function<
double(
const std::array<double, D>&)> gfunc,
196 std::function<
double(
const std::array<double, D>&)> hfunc)
200 auto pinfo = this->
getDomain().getPatchInfoVector()[i];
202 if (!pinfo.hasNbr(s)) {
203 double h2 = pow(pinfo.spacings[s.getAxisIndex()], 2);
205 Loop::Nested<D - 1>(ld.getStart(), ld.getEnd(), [&](
const std::array<int, D - 1>& coord) {
206 std::array<double, D> real_coord;
207 DomainTools::GetRealCoordBound<D>(pinfo, coord, s, real_coord);
208 std::array<double, D> other_real_coord = real_coord;
209 if (s.isLowerOnAxis()) {
210 other_real_coord[s.getAxisIndex()] -= pinfo.spacings[s.getAxisIndex()];
212 other_real_coord[s.getAxisIndex()] += pinfo.spacings[s.getAxisIndex()];
214 ld[coord] -= 2 * gfunc(real_coord) * hfunc(real_coord) / h2;
221 extern template class StarPatchOperator<2>;
222 extern template class StarPatchOperator<3>;
ComponentView< double, D > getComponentView(int component_index, int patch_local_index)
Get the ComponentView for the specified patch and component.
Definition: Vector.h:336
static void Nested(A start, A end, T lambda)
Loop over a range of integer coordinates.
Definition: Loops.h:125
static void Unroll(T lambda)
Unroll a fixed-length loop.
Definition: Loops.h:72
const std::array< int, D > & getStrides() const
Get the strides of the patch in each direction.
Definition: View.h:203
bool hasNbr(Face< D, M > s) const
Return whether the patch has a neighbor.
Definition: PatchInfo.h:284
View< T, M+1 > getSliceOn(Face< D, M > f, const std::array< int, D - M > &offset) const
Get the slice on a given face.
Definition: PatchView.h:200
View< typename std::remove_const< T >::type, M+1 > getGhostSliceOn(Face< D, M > f, const std::array< size_t, D - M > &offset) const
Get the gosts slice on a given face.
Definition: PatchView.h:219
virtual void fillGhost(const Vector< D > &u) const =0
Fill ghost cells on a vector.
StarPatchOperator< D > * clone() const override
Get a clone of this operator.
Definition: StarPatchOperator.h:77
Implements a variable coefficient Laplacian f=Div[h*Grad[u]].
Definition: StarPatchOperator.h:46
Uses a collection of PatchInfo objects to represent the domain of the problem.
Definition: Domain.h:50
int local_index
The local index of the patch in the Domain.
Definition: PatchInfo.h:69
View< T, M > getSliceOn(Face< D, M > f, const std::array< int, D - M > &offset) const
Get the slice on a given face.
Definition: ComponentView.h:194
StarPatchOperator(const Vector< D > &coeffs, const Domain< D > &domain, const GhostFiller< D > &ghost_filler)
Construct a new StarPatchOperator object.
Definition: StarPatchOperator.h:61
View for accessing data of a patch. It supports variable striding.
Definition: PatchView.h:37
The ThunderEgg namespace.
Definition: BiLinearGhostFiller.h:31
void applySinglePatch(const PatchInfo< D > &pinfo, const PatchView< const double, D > &u_view, const PatchView< double, D > &f_view) const override
Apply the operator to a single patch.
Definition: StarPatchOperator.h:112
Fills ghost cells on patches.
Definition: GhostFiller.h:36
Contains metadata for a patch.
Definition: PatchInfo.h:51
int getNumGhostCells() const
get the number of ghost cell on each side of a patch
Definition: Domain.h:295
const Domain< D > & getDomain() const
Get the Domain object associated with this PatchOperator.
Definition: PatchOperator.h:147
void applySinglePatchWithInternalBoundaryConditions(const PatchInfo< D > &pinfo, const PatchView< const double, D > &u_view, const PatchView< double, D > &f_view) const override
Apply the operator to a single patch.
Definition: StarPatchOperator.h:118
This is an Operator where derived classes only have to implement the two virtual functions that opera...
Definition: PatchOperator.h:40
std::array< double, D > spacings
The cell spacings in each direction.
Definition: PatchInfo.h:125
void modifyRHSForInternalBoundaryConditions(const PatchInfo< D > &pinfo, const PatchView< const double, D > &u_view, const PatchView< double, D > &f_view) const override
Treat the internal patch boundaries as domain boundaires and modify RHS accordingly.
Definition: StarPatchOperator.h:168
PatchView< double, D > getPatchView(int patch_local_index)
Get the View objects for the specified patch index of View object will correspond to component index.
Definition: Vector.h:358
Vector class for use in thunderegg.
Definition: Vector.h:42
Enum-style class for the faces of an n-dimensional cube.
Definition: Face.h:41
int getNumLocalPatches() const
Get the number of local patches.
Definition: Vector.h:316
void addDrichletBCToRHS(Vector< D > &f, std::function< double(const std::array< double, D > &)> gfunc, std::function< double(const std::array< double, D > &)> hfunc)
Helper function for adding Dirichlet boundary conditions to right hand side.
Definition: StarPatchOperator.h:194
ThunderEgg runtime exception.
Definition: RuntimeError.h:36