ABLATE Source Documentation  0.12.34
subDomain.hpp
1 #ifndef ABLATELIBRARY_SUBDOMAIN_HPP
2 #define ABLATELIBRARY_SUBDOMAIN_HPP
3 #include <petsc.h>
4 #include <algorithm>
5 #include <map>
6 #include <mathFunctions/fieldFunction.hpp>
7 #include <memory>
8 #include <string>
9 #include "constFieldAccessor.hpp"
10 #include "domain.hpp"
11 #include "fieldAccessor.hpp"
12 #include "fieldDescription.hpp"
13 #include "io/serializable.hpp"
14 #include "range.hpp"
15 #include "utilities/petscUtilities.hpp"
16 
17 namespace ablate::domain {
18 
19 class SubDomain : public io::Serializable {
20  private:
22  inline static const std::string defaultName = "domain";
23 
25  Domain& domain;
26 
28  std::string name;
29 
31  DMLabel label;
32 
34  PetscInt labelValue;
35 
37  IS fieldMap;
38 
40  std::map<std::string, Field> fieldsByName;
41 
43  std::map<FieldLocation, std::vector<Field>> fieldsByType;
44 
46  PetscDS discreteSystem;
47  PetscDS auxDiscreteSystem{};
48 
50  DM auxDM;
51 
53  Vec auxLocalVec;
54 
56  Vec auxGlobalVec;
57 
59  DM subDM;
60  Vec subSolutionVec;
61  DM subAuxDM;
62  Vec subAuxVec;
63 
65  std::vector<std::shared_ptr<mathFunctions::FieldFunction>> exactSolutions;
66 
77  void CopyGlobalToSubVector(DM subDM, DM gDM, Vec subVec, Vec globVec, const std::vector<Field>& subFields, const std::vector<Field>& gFields = {}, bool localVector = false) const;
78 
89  void CopySubVectorToGlobal(DM subDM, DM gDM, Vec subVec, Vec globVec, const std::vector<Field>& subFields, const std::vector<Field>& gFields = {}, bool localVector = false) const;
90 
91  public:
98  SubDomain(Domain& domain, PetscInt dsNumber, const std::vector<std::shared_ptr<FieldDescription>>& allAuxFields);
99  ~SubDomain() override;
100 
101  // prevent unintended copy of the subdomain
102  SubDomain(const SubDomain& temp_obj) = delete;
103 
104  // prevent unintended copy of the subdomain
105  SubDomain& operator=(const SubDomain& temp_obj) = delete;
106 
111 
117  [[nodiscard]] inline const Field& GetField(const std::string& fieldName) const {
118  if (fieldsByName.count(fieldName)) {
119  return fieldsByName.at(fieldName);
120  } else {
121  throw std::invalid_argument("Cannot locate field " + fieldName + " in subDomain " + name);
122  }
123  }
124 
131  [[nodiscard]] inline const Field& GetField(PetscInt id, FieldLocation location = FieldLocation::SOL) const {
132  auto field = std::find_if(fieldsByName.begin(), fieldsByName.end(), [location, id](auto pair) { return pair.second.location == location && pair.second.id == id; });
133  if (field != fieldsByName.end()) {
134  return field->second;
135  } else {
136  throw std::invalid_argument("Cannot locate field with id " + std::to_string(id) + " in subDomain " + name);
137  }
138  }
139 
145  [[nodiscard]] inline const std::vector<Field>& GetFields(FieldLocation type = FieldLocation::SOL) const { return fieldsByType.at(type); }
146 
153  [[nodiscard]] std::vector<Field> GetFields(FieldLocation type, std::string_view tag) const;
154 
160  [[nodiscard]] inline DM GetFieldDM(const Field& field) const noexcept {
161  switch (field.location) {
162  case FieldLocation::SOL:
163  return GetDM();
164  case FieldLocation::AUX:
165  return GetAuxDM();
166  }
167  return nullptr;
168  }
169 
175  [[nodiscard]] inline Vec GetVec(const Field& field) const noexcept {
176  switch (field.location) {
177  case FieldLocation::SOL:
178  return GetSolutionVector();
179  case FieldLocation::AUX:
180  return GetAuxVector();
181  }
182  return nullptr;
183  }
184 
190  inline Vec GetGlobalVec(const Field& field) noexcept {
191  switch (field.location) {
192  case FieldLocation::SOL:
193  return GetSolutionVector();
194  case FieldLocation::AUX:
195  return GetAuxGlobalVector();
196  }
197  return nullptr;
198  }
199 
205  [[nodiscard]] inline auto GetSolutionAccessor(const Field& field) const {
206  if (field.location != FieldLocation::SOL) {
207  throw std::invalid_argument("ablate::domain::SubDomain::GetSolutionAccessor requires a Solution Field");
208  }
210  }
211 
217  [[nodiscard]] inline auto GetConstSolutionAccessor(const Field& field) const {
218  if (field.location != FieldLocation::SOL) {
219  throw std::invalid_argument("ablate::domain::SubDomain::GetSolutionAccessor requires a Solution Field");
220  }
222  }
223 
229  [[nodiscard]] inline auto GetAuxAccessor(const Field& field) const {
230  if (field.location != FieldLocation::AUX) {
231  throw std::invalid_argument("ablate::domain::SubDomain::GetSolutionAccessor requires a Aux Field");
232  }
234  }
235 
241  [[nodiscard]] inline auto GetConstAuxAccessor(const Field& field) const {
242  if (field.location != FieldLocation::AUX) {
243  throw std::invalid_argument("ablate::domain::SubDomain::GetSolutionAccessor requires a Aux Field");
244  }
246  }
247 
253  [[nodiscard]] inline auto GetSolutionAccessor(const std::string& fieldName) const { return GetSolutionAccessor(GetField(fieldName)); }
254 
260  [[nodiscard]] inline auto GetConstSolutionAccessor(const std::string& fieldName) const { return GetConstSolutionAccessor(GetField(fieldName)); }
261 
267  [[nodiscard]] inline auto GetAuxAccessor(const std::string& fieldName) { return GetAuxAccessor(GetField(fieldName)); }
268 
274  [[nodiscard]] inline auto GetConstAuxAccessor(const std::string& fieldName) { return GetAuxAccessor(GetField(fieldName)); }
275 
281  inline bool ContainsField(const std::string& fieldName) { return fieldsByName.count(fieldName) > 0; }
282 
287  [[nodiscard]] bool InRegion(const domain::Region&) const;
288 
294  [[nodiscard]] inline bool InRegion(PetscInt point) const {
295  if (!label) {
296  return true;
297  }
298  PetscInt ptValue;
299  DMLabelGetValue(label, point, &ptValue) >> utilities::PetscUtilities::checkError;
300  return ptValue == labelValue;
301  }
302 
307  inline MPI_Comm GetComm() const { return PetscObjectComm((PetscObject)domain.GetDM()); }
308 
313  inline DMLabel GetLabel() { return label; }
314 
319  inline const std::string& GetId() const override { return name; }
320 
325  inline PetscInt GetDimensions() const noexcept { return domain.GetDimensions(); }
326 
332  PetscObject GetPetscFieldObject(const Field& field);
333 
338  [[nodiscard]] inline DM& GetDM() const noexcept { return domain.GetDM(); }
339 
345  [[nodiscard]] inline DM GetAuxDM() const noexcept { return auxDM; }
346 
351  [[nodiscard]] inline Vec GetSolutionVector() const noexcept { return domain.GetSolutionVector(); }
352 
357  [[nodiscard]] inline Vec GetAuxVector() const noexcept { return auxLocalVec; }
358 
362  Vec GetAuxGlobalVector();
363 
369  DM GetSubDM();
370 
375  Vec GetSubSolutionVector();
376 
382  DM GetSubAuxDM();
383 
388  Vec GetSubAuxVector();
389 
394  inline PetscDS GetDiscreteSystem() { return discreteSystem; }
395 
400  inline PetscDS GetAuxDiscreteSystem() { return auxDiscreteSystem; }
401 
406  [[nodiscard]] inline PetscInt GetNumberFields() const { return (PetscInt)fieldsByName.size(); }
407 
413  void ProjectFieldFunctionsToLocalVector(const std::vector<std::shared_ptr<mathFunctions::FieldFunction>>& fieldFunctions, Vec locVec, PetscReal time = 0.0) const;
414 
421  PetscErrorCode ProjectFieldFunctionsToSubDM(const std::vector<std::shared_ptr<mathFunctions::FieldFunction>>& initialization, Vec globVec, PetscReal time = 0.0);
422 
427  void SetsExactSolutions(const std::vector<std::shared_ptr<mathFunctions::FieldFunction>>& exactSolutions);
428 
436  PetscErrorCode GetFieldGlobalVector(const Field&, IS* vecIs, Vec* vec, DM* subdm);
437 
445  PetscErrorCode RestoreFieldGlobalVector(const Field&, IS* vecIs, Vec* vec, DM* subdm);
446 
455  PetscErrorCode GetFieldLocalVector(const Field&, PetscReal time, IS* vecIs, Vec* vec, DM* subdm);
456 
464  PetscErrorCode RestoreFieldLocalVector(const Field&, IS* vecIs, Vec* vec, DM* subdm);
465 
472  PetscErrorCode Save(PetscViewer viewer, PetscInt sequenceNumber, PetscReal time) override;
473 
480  PetscErrorCode Restore(PetscViewer viewer, PetscInt sequenceNumber, PetscReal time) override;
481 
486  void CreateEmptySubDM(DM* inDM, std::shared_ptr<domain::Region> region = {});
487 
494  void GetRange(const std::shared_ptr<ablate::domain::Region>& region, PetscInt depth, ablate::domain::Range& range) const { ablate::domain::GetRange(this->GetDM(), region, depth, range); }
495 
501  void GetCellRange(const std::shared_ptr<ablate::domain::Region>& region, ablate::domain::Range& cellRange) const { ablate::domain::GetCellRange(this->GetDM(), region, cellRange); }
502 
508  void GetFaceRange(const std::shared_ptr<ablate::domain::Region>& region, ablate::domain::Range& faceRange) const { ablate::domain::GetFaceRange(this->GetDM(), region, faceRange); }
509 
514  void RestoreRange(ablate::domain::Range& range) const { ablate::domain::RestoreRange(range); }
515 };
516 
517 } // namespace ablate::domain
518 #endif // ABLATELIBRARY_SUBDOMAIN_HPP
Definition: constFieldAccessor.hpp:12
Definition: domain.hpp:29
Vec GetSolutionVector()
Definition: domain.hpp:81
Definition: fieldAccessor.hpp:12
Definition: region.hpp:11
Definition: subDomain.hpp:19
Vec GetAuxGlobalVector()
Definition: subDomain.cpp:212
void GetRange(const std::shared_ptr< ablate::domain::Region > &region, PetscInt depth, ablate::domain::Range &range) const
Definition: subDomain.hpp:494
auto GetAuxAccessor(const std::string &fieldName)
Definition: subDomain.hpp:267
void ProjectFieldFunctionsToLocalVector(const std::vector< std::shared_ptr< mathFunctions::FieldFunction >> &fieldFunctions, Vec locVec, PetscReal time=0.0) const
Definition: subDomain.cpp:700
void SetsExactSolutions(const std::vector< std::shared_ptr< mathFunctions::FieldFunction >> &exactSolutions)
Definition: subDomain.cpp:613
void CreateSubDomainStructures()
Definition: subDomain.cpp:142
SubDomain(Domain &domain, PetscInt dsNumber, const std::vector< std::shared_ptr< FieldDescription >> &allAuxFields)
Definition: subDomain.cpp:8
bool InRegion(const domain::Region &) const
Definition: subDomain.cpp:471
PetscErrorCode GetFieldLocalVector(const Field &, PetscReal time, IS *vecIs, Vec *vec, DM *subdm)
Definition: subDomain.cpp:556
void RestoreRange(ablate::domain::Range &range) const
Definition: subDomain.hpp:514
const std::string & GetId() const override
Definition: subDomain.hpp:319
PetscErrorCode GetFieldGlobalVector(const Field &, IS *vecIs, Vec *vec, DM *subdm)
Definition: subDomain.cpp:532
DM GetSubDM()
Definition: subDomain.cpp:220
auto GetSolutionAccessor(const Field &field) const
Definition: subDomain.hpp:205
auto GetConstSolutionAccessor(const Field &field) const
Definition: subDomain.hpp:217
PetscErrorCode ProjectFieldFunctionsToSubDM(const std::vector< std::shared_ptr< mathFunctions::FieldFunction >> &initialization, Vec globVec, PetscReal time=0.0)
Definition: subDomain.cpp:168
PetscDS GetDiscreteSystem()
Definition: subDomain.hpp:394
auto GetSolutionAccessor(const std::string &fieldName) const
Definition: subDomain.hpp:253
PetscErrorCode RestoreFieldGlobalVector(const Field &, IS *vecIs, Vec *vec, DM *subdm)
Definition: subDomain.cpp:545
void GetFaceRange(const std::shared_ptr< ablate::domain::Region > &region, ablate::domain::Range &faceRange) const
Definition: subDomain.hpp:508
auto GetAuxAccessor(const Field &field) const
Definition: subDomain.hpp:229
void GetCellRange(const std::shared_ptr< ablate::domain::Region > &region, ablate::domain::Range &cellRange) const
Definition: subDomain.hpp:501
Vec GetVec(const Field &field) const noexcept
Definition: subDomain.hpp:175
Vec GetGlobalVec(const Field &field) noexcept
Definition: subDomain.hpp:190
DM GetFieldDM(const Field &field) const noexcept
Definition: subDomain.hpp:160
PetscDS GetAuxDiscreteSystem()
Definition: subDomain.hpp:400
auto GetConstSolutionAccessor(const std::string &fieldName) const
Definition: subDomain.hpp:260
bool ContainsField(const std::string &fieldName)
Definition: subDomain.hpp:281
PetscInt GetDimensions() const noexcept
Definition: subDomain.hpp:325
const Field & GetField(PetscInt id, FieldLocation location=FieldLocation::SOL) const
Definition: subDomain.hpp:131
DM GetSubAuxDM()
Definition: subDomain.cpp:286
DM GetAuxDM() const noexcept
Definition: subDomain.hpp:345
PetscInt GetNumberFields() const
Definition: subDomain.hpp:406
const std::vector< Field > & GetFields(FieldLocation type=FieldLocation::SOL) const
Definition: subDomain.hpp:145
const Field & GetField(const std::string &fieldName) const
Definition: subDomain.hpp:117
Vec GetAuxVector() const noexcept
Definition: subDomain.hpp:357
Vec GetSolutionVector() const noexcept
Definition: subDomain.hpp:351
bool InRegion(PetscInt point) const
Definition: subDomain.hpp:294
PetscErrorCode Restore(PetscViewer viewer, PetscInt sequenceNumber, PetscReal time) override
Definition: subDomain.cpp:682
Vec GetSubAuxVector()
Definition: subDomain.cpp:334
PetscErrorCode Save(PetscViewer viewer, PetscInt sequenceNumber, PetscReal time) override
Definition: subDomain.cpp:635
DM & GetDM() const noexcept
Definition: subDomain.hpp:338
Vec GetSubSolutionVector()
Definition: subDomain.cpp:259
auto GetConstAuxAccessor(const Field &field) const
Definition: subDomain.hpp:241
MPI_Comm GetComm() const
Definition: subDomain.hpp:307
void CreateEmptySubDM(DM *inDM, std::shared_ptr< domain::Region > region={})
Definition: subDomain.cpp:748
PetscErrorCode RestoreFieldLocalVector(const Field &, IS *vecIs, Vec *vec, DM *subdm)
Definition: subDomain.cpp:594
auto GetConstAuxAccessor(const std::string &fieldName)
Definition: subDomain.hpp:274
PetscObject GetPetscFieldObject(const Field &field)
Definition: subDomain.cpp:515
DMLabel GetLabel()
Definition: subDomain.hpp:313
Definition: serializable.hpp:13
static utilities::PetscUtilities::ErrorChecker checkError
Definition: petscUtilities.hpp:46
Definition: field.hpp:17
Definition: range.hpp:11