ThunderEgg  1.0.0
PatchSolver.h
Go to the documentation of this file.
1 /***************************************************************************
2  * ThunderEgg, a library for solvers on adaptively refined block-structured
3  * Cartesian grids.
4  *
5  * Copyright (c) 2019-2021 Scott Aiton
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <https://www.gnu.org/licenses/>.
19  ***************************************************************************/
20 
21 #ifndef THUNDEREGG_PATCHSOLVER_H
22 #define THUNDEREGG_PATCHSOLVER_H
23 
29 #include <ThunderEgg/Domain.h>
31 #include <ThunderEgg/GhostFiller.h>
32 #include <ThunderEgg/Operator.h>
33 #include <ThunderEgg/Vector.h>
34 
35 namespace ThunderEgg {
41 template<int D>
43  : public virtual Operator<D>
44  , public virtual GMG::Smoother<D>
45 {
46 private:
50  Domain<D> domain;
54  std::shared_ptr<const GhostFiller<D>> ghost_filler;
55 
56 public:
65  PatchSolver(const Domain<D>& domain, const GhostFiller<D>& ghost_filler)
66  : domain(domain)
67  , ghost_filler(ghost_filler.clone())
68  {}
72  virtual ~PatchSolver() {}
78  virtual PatchSolver<D>* clone() const override = 0;
84  const Domain<D>& getDomain() const { return domain; }
90  const GhostFiller<D>& getGhostFiller() const { return *ghost_filler; }
98  virtual void solveSinglePatch(const PatchInfo<D>& pinfo,
99  const PatchView<const double, D>& f_view,
100  const PatchView<double, D>& u_view) const = 0;
107  virtual void apply(const Vector<D>& f, Vector<D>& u) const override
108  {
109  if constexpr (ENABLE_DEBUG) {
110  if (u.getNumLocalPatches() != this->domain.getNumLocalPatches()) {
111  throw RuntimeError("u vector is incorrect length");
112  }
113  if (f.getNumLocalPatches() != this->domain.getNumLocalPatches()) {
114  throw RuntimeError("f vector is incorrect length");
115  }
116  }
117  u.setWithGhost(0);
118  if (domain.hasTimer()) {
119  domain.getTimer()->startDomainTiming(domain.getId(), "Total Patch Solve");
120  }
121  for (const PatchInfo<D>& pinfo : domain.getPatchInfoVector()) {
122  if (domain.hasTimer()) {
123  domain.getTimer()->start("Single Patch Solve");
124  }
125  PatchView<const double, D> f_view = f.getPatchView(pinfo.local_index);
126  PatchView<double, D> u_view = u.getPatchView(pinfo.local_index);
127  solveSinglePatch(pinfo, f_view, u_view);
128  if (domain.hasTimer()) {
129  domain.getTimer()->stop("Single Patch Solve");
130  }
131  }
132  if (domain.hasTimer()) {
133  domain.getTimer()->stopDomainTiming(domain.getId(), "Total Patch Solve");
134  }
135  }
142  virtual void smooth(const Vector<D>& f, Vector<D>& u) const override
143  {
144  if constexpr (ENABLE_DEBUG) {
145  if (u.getNumLocalPatches() != this->domain.getNumLocalPatches()) {
146  throw RuntimeError("u vector is incorrect length");
147  }
148  if (f.getNumLocalPatches() != this->domain.getNumLocalPatches()) {
149  throw RuntimeError("f vector is incorrect length");
150  }
151  }
152  if (domain.hasTimer()) {
153  domain.getTimer()->startDomainTiming(domain.getId(), "Total Patch Smooth");
154  }
155  ghost_filler->fillGhost(u);
156  for (const PatchInfo<D>& pinfo : domain.getPatchInfoVector()) {
157  if (domain.hasTimer()) {
158  domain.getTimer()->startPatchTiming(pinfo.id, domain.getId(), "Single Patch Solve");
159  }
160  PatchView<const double, D> f_view = f.getPatchView(pinfo.local_index);
161  PatchView<double, D> u_view = u.getPatchView(pinfo.local_index);
162  solveSinglePatch(pinfo, f_view, u_view);
163  if (domain.hasTimer()) {
164  domain.getTimer()->stopPatchTiming(pinfo.id, domain.getId(), "Single Patch Solve");
165  }
166  }
167  if (domain.hasTimer()) {
168  domain.getTimer()->stopDomainTiming(domain.getId(), "Total Patch Smooth");
169  }
170  }
171 };
172 } // namespace ThunderEgg
173 #endif
ThunderEgg::Domain::hasTimer
bool hasTimer() const
Check if the Domain has a timer associated with it.
Definition: Domain.h:335
ThunderEgg::PatchSolver::getDomain
const Domain< D > & getDomain() const
Get the Domain object.
Definition: PatchSolver.h:84
ThunderEgg::PatchSolver::apply
virtual void apply(const Vector< D > &f, Vector< D > &u) const override
Solve all the patches in the domain, assuming zero boundary conditions for the patches.
Definition: PatchSolver.h:107
ThunderEgg::Domain::getTimer
std::shared_ptr< Timer > getTimer() const
Get the Timer object.
Definition: Domain.h:330
Vector.h
Vector class.
ThunderEgg::PatchSolver::clone
virtual PatchSolver< D > * clone() const override=0
Clone this patch solver.
ThunderEgg::PatchSolver
Solves the problem on the patches using a specified interface value.
Definition: PatchSolver.h:42
ThunderEgg::PatchSolver::~PatchSolver
virtual ~PatchSolver()
Destroy the Patch Solver object.
Definition: PatchSolver.h:72
Smoother.h
Smoother class.
Operator.h
Operator class.
ThunderEgg::PatchSolver::smooth
virtual void smooth(const Vector< D > &f, Vector< D > &u) const override
Solve all the patches in the domain, using the values in u for the boundary conditions.
Definition: PatchSolver.h:142
ThunderEgg::Domain
Uses a collection of PatchInfo objects to represent the domain of the problem.
Definition: Domain.h:50
ThunderEgg::PatchView
View for accessing data of a patch. It supports variable striding.
Definition: PatchView.h:37
ThunderEgg
The ThunderEgg namespace.
Definition: BiLinearGhostFiller.h:31
GhostFiller.h
GhostFiller class.
ThunderEgg::GhostFiller
Fills ghost cells on patches.
Definition: GhostFiller.h:36
ThunderEgg::PatchInfo
Contains metadata for a patch.
Definition: PatchInfo.h:51
ThunderEgg::Vector::setWithGhost
void setWithGhost(double alpha)
set all values in the vector (including ghost cells)
Definition: Vector.h:404
ThunderEgg::PatchSolver::solveSinglePatch
virtual void solveSinglePatch(const PatchInfo< D > &pinfo, const PatchView< const double, D > &f_view, const PatchView< double, D > &u_view) const =0
Perform a single solve over a patch.
ThunderEgg::PatchSolver::getGhostFiller
const GhostFiller< D > & getGhostFiller() const
Get the GhostFiller object.
Definition: PatchSolver.h:90
Domain.h
Domain class.
ThunderEgg::PatchSolver::PatchSolver
PatchSolver(const Domain< D > &domain, const GhostFiller< D > &ghost_filler)
Construct a new PatchSolver object.
Definition: PatchSolver.h:65
ThunderEgg::Operator
Base class for operators.
Definition: Operator.h:37
ThunderEgg::Vector::getPatchView
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
ThunderEgg::Vector
Vector class for use in thunderegg.
Definition: Vector.h:42
ThunderEgg::Domain::getPatchInfoVector
const std::vector< PatchInfo< D > > & getPatchInfoVector() const
Get a vector of PatchInfo pointers where index in the vector corresponds to the patch's local index.
Definition: Domain.h:259
ThunderEgg::GMG::Smoother
Abstract class for smoothing operators.
Definition: Smoother.h:34
ThunderEgg::Vector::getNumLocalPatches
int getNumLocalPatches() const
Get the number of local patches.
Definition: Vector.h:316
ThunderEgg::Domain::getId
int getId() const
Get the domain's id.
Definition: Domain.h:341
ThunderEgg::RuntimeError
ThunderEgg runtime exception.
Definition: RuntimeError.h:36