Panzer  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Panzer_STK_PeriodicBC_MatchConditions.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Panzer: A partial differential equation assembly
4 // engine for strongly coupled complex multiphysics systems
5 //
6 // Copyright 2011 NTESS and the Panzer contributors.
7 // SPDX-License-Identifier: BSD-3-Clause
8 // *****************************************************************************
9 // @HEADER
10 
11 #ifndef __Panzer_STK_PeriodicBC_MatchConditions_hpp__
12 #define __Panzer_STK_PeriodicBC_MatchConditions_hpp__
13 
14 #include "Teuchos_Tuple.hpp"
15 
16 #include <vector>
17 #include <string>
18 
19 namespace panzer_stk {
20 
23 class CoordMatcher {
24  double error_;
25  int index_;
26  bool relative_; // compute error relative to length of domain
27  char labels_[3];
28 
29  void buildLabels()
30  { labels_[0] = 'x'; labels_[1] = 'y'; labels_[2] = 'z'; }
31 
32  void parseParams(const std::vector<std::string> & params)
33  {
34  std::string errStr = "CoordMatcher \"" + std::string(1,labels_[index_]) + "-coord\" takes at most two parameters <tol, relative>";
35  TEUCHOS_TEST_FOR_EXCEPTION(params.size()>2,std::logic_error,errStr);
36 
37  // read in string, get double
38  if(params.size()>0) {
39  std::stringstream ss;
40  ss << params[0];
41  ss >> error_;
42  if(params.size()==2){
43  std::string errStr2 = params[1] + " is not a valid periodic option (try \"relative\")";
44  TEUCHOS_TEST_FOR_EXCEPTION(params[1]!="relative",std::logic_error,errStr2);
45  relative_ = true;
46  }
47  }
48  // else use default value for error
49  }
50 
51 public:
53  CoordMatcher(int index) : error_(1e-8),index_(index),relative_(false) { buildLabels(); }
54  CoordMatcher(int index,double error) : error_(error),index_(index),relative_(false) { buildLabels(); }
55  CoordMatcher(int index,const std::vector<std::string> & params) : error_(1e-8),index_(index),relative_(false)
56  { buildLabels(); parseParams(params); }
57 
59 
61  const Teuchos::Tuple<double,3> & b) const
62  {
63  double error = error_;
64  if(relative_) // scale error by length of domain
65  error*=std::fabs(a[1-index_]-b[1-index_]);
66  return std::fabs(a[index_]-b[index_])<error; /* I'm being lazy here! */
67  }
68 
69  std::string getString() const
70  {
71  std::stringstream ss;
72  ss << labels_[index_] << "-coord <tol=" << error_ << ">";
73  return ss.str();
74  }
75 
76  int getIndex() const {return index_;}
77 
79  {
80  // This assumes a 2D x-y mesh even though the object supports the
81  // z direction. Once in 3D you need the PlaneMatcher.
82  TEUCHOS_ASSERT(index_ != 2);
83  if (index_ == 0)
84  return 1;
85  return 0;
86  }
87 
88  double getAbsoluteTolerance() const {return error_;}
89 
90  void transform(double * ptB, const std::vector<double> & centroidA) const
91  {
92  // Instead of matching directly, shift pt B given the centroid
93  // of side A
94  // For now, we assume at 2D x-y mesh as above so just need
95  // to overwrite the coordinate in the periodic direction
96 
97  const int periodicIndex = this->getPeriodicDirection();
98  ptB[periodicIndex] = centroidA[periodicIndex];
99 
100  return;
101  }
102 };
103 
107  double error_;
109  bool relative_; // compute error relative to length of domain
110  char labels_[3];
111 
112  void buildLabels()
113  { labels_[0] = 'x'; labels_[1] = 'y'; labels_[2] = 'z'; }
114 
115  void parseParams(const std::vector<std::string> & params)
116  {
117  std::string errStr = "PlaneMatcher \"" + std::string(1,labels_[index0_])+std::string(1,labels_[index1_])
118  + "-coord\" takes at most two parameter <tol, relative>";
119  TEUCHOS_TEST_FOR_EXCEPTION(params.size()>2,std::logic_error,errStr);
120 
121  // read in string, get double
122  if(params.size()>0) {
123  std::stringstream ss;
124  ss << params[0];
125  ss >> error_;
126  if(params.size()==2){
127  if (params[1] == "3D") {
128  // Warn user but continue
129  std::cout << "WARNING : Keyword " << params[1] << " not needed for PlaneMatcher" << std::endl;
130  return;
131  }
132  std::string errStr2 = params[1] + " is not a valid periodic option (try \"relative\")";
133  TEUCHOS_TEST_FOR_EXCEPTION(params[1]!="relative",std::logic_error,errStr2);
134  relative_ = true;
135  }
136  }
137  // else use default value for error
138  return;
139  }
140 
141 public:
142  PlaneMatcher(int index0,int index1) : error_(1e-8),index0_(index0), index1_(index1), relative_(false)
143  { TEUCHOS_ASSERT(index0!=index1); buildLabels(); }
144 
145  PlaneMatcher(int index0,int index1,double error) : error_(error),index0_(index0), index1_(index1), relative_(false)
146  { TEUCHOS_ASSERT(index0!=index1); buildLabels(); }
147 
148  PlaneMatcher(int index0,int index1,const std::vector<std::string> & params)
149  : error_(1e-8), index0_(index0), index1_(index1), relative_(false)
150  { TEUCHOS_ASSERT(index0!=index1); buildLabels(); parseParams(params); }
151 
153  { buildLabels(); }
154 
156  const Teuchos::Tuple<double,3> & b) const
157  {
158  double error = error_;
159  if(relative_) // scale error by length of domain in normal direction
160  error*=std::fabs(a[3-index0_-index1_]-b[3-index0_-index1_]);
161  return (std::fabs(a[index0_]-b[index0_])<error_)
162  && (std::fabs(a[index1_]-b[index1_])<error_) ; /* I'm being lazy here! */
163  }
164 
165  std::string getString() const
166  {
167  std::stringstream ss;
168  ss << labels_[index0_] << labels_[index1_] << "-coord <tol=" << error_ << ">";
169  return ss.str();
170  }
171 
172  int getIndex0() const {return index0_;}
173  int getIndex1() const {return index1_;}
175  {
176  if (index0_ ==0) {
177  if (index1_ == 1)
178  return 2; // match x,y=periodic in z
179  else
180  return 1; // match x,z=periodic in y
181  }
182  else if (index0_ == 1) {
183  if (index1_ == 0)
184  return 2; // match y,x=periodic in z
185  else
186  return 0; // match y,z=periodic in x
187  }
188  else {
189  if (index1_ == 0)
190  return 1; // match z,x=periodic in y
191  else
192  return 0; // match z,y=periodic in x
193  }
194  }
195 
196  double getAbsoluteTolerance() const {return error_;}
197 
198  void transform(double * ptB, const std::vector<double> & centroidA) const
199  {
200  // Instead of matching directly, shift pt B given the centroid
201  // of side A
202  // For now, we assume the planes are aligned with one of the
203  // coordinate axes so we just need to overwrite the coordinate
204  // in the periodic direction
205 
206  const int periodicIndex = this->getPeriodicDirection();
207  ptB[periodicIndex] = centroidA[periodicIndex];
208 
209  return;
210  }
211 };
212 
216  double error_;
218  char labels_[3];
219 
220  void buildLabels()
221  { labels_[0] = 'x'; labels_[1] = 'y'; labels_[2] = 'z'; }
222 
223  void parseParams(const std::vector<std::string> & params)
224  {
225  std::string errStr = "QuarterPlaneMatcher \"(" + std::string(1,labels_[index0a_])+std::string(1,labels_[index0b_])+")"+std::string(1,labels_[index1_])
226  + "-quarter-coord\" takes only one parameter <tol>";
227  TEUCHOS_TEST_FOR_EXCEPTION(params.size()>1,std::logic_error,errStr);
228 
229  // read in string, get double
230  if(params.size()==1) {
231  std::stringstream ss;
232  ss << params[0];
233  ss >> error_;
234  }
235  // else use default value for error
236  }
237 
238 public:
239  QuarterPlaneMatcher(int index0a,int index0b,int index1)
240  : error_(1e-8), index0a_(index0a), index0b_(index0b), index1_(index1)
241  { TEUCHOS_ASSERT(index0a!=index1); TEUCHOS_ASSERT(index0b!=index1); buildLabels(); }
242 
243  QuarterPlaneMatcher(int index0a,int index0b,int index1,double error)
244  : error_(error), index0a_(index0a), index0b_(index0b), index1_(index1)
245  { TEUCHOS_ASSERT(index0a!=index1); TEUCHOS_ASSERT(index0b!=index1); buildLabels(); }
246 
247  QuarterPlaneMatcher(int index0a,int index0b,int index1,const std::vector<std::string> & params)
248  : error_(1e-8), index0a_(index0a), index0b_(index0b), index1_(index1)
249  { TEUCHOS_ASSERT(index0a!=index1); TEUCHOS_ASSERT(index0b!=index1); buildLabels(); parseParams(params); }
250 
253  { buildLabels(); }
254 
256  const Teuchos::Tuple<double,3> & b) const
257  { return (std::fabs(a[index0a_]-b[index0b_])<error_)
258  && (std::fabs(a[index1_]-b[index1_])<error_) ; /* I'm being lazy here! */ }
259 
260  std::string getString() const
261  {
262  std::stringstream ss;
263  ss << "(" << labels_[index0a_] << labels_[index0b_] << ")" << labels_[index1_] << "-quarter-coord <tol=" << error_ << ">";
264  return ss.str();
265  }
266 
267  double getAbsoluteTolerance() const {return error_;}
268 
269  void transform(double * ptB, const std::vector<double> & centroidA) const
270  {
271  // Instead of matching directly, shift pt B given the centroid
272  // of side A
273  // For now, we assume the planes are aligned with one of the
274  // coordinate axes
275  // We leave ptB[index1_] alone,
276  // put ptB[index0b_] in the index0a_ slot and replace it with
277  // centroidA[index0b_] which is the fixed value for plane B
278 
279  ptB[index0a_] = ptB[index0b_];
280  ptB[index0b_] = centroidA[index0b_];
281 
282  return;
283  }
284 };
285 
294  double error_;
296  int index0_;
299 public:
300  enum class MirrorPlane : int {
301  XZ_PLANE=0,
302  YZ_PLANE=1
303  };
304  WedgeMatcher(MirrorPlane mp,const std::vector<std::string> & params )
305  : error_(1e-8),index0_(0),is_three_d_(true)
306  {
307  if (mp == MirrorPlane::XZ_PLANE)
308  index0_ = 1;
309  else // YZ_PLANE
310  index0_ = 0;
311 
312  TEUCHOS_TEST_FOR_EXCEPTION(params.size() > 2,std::logic_error,"WedgeMatcher can only have one or two option parameters (tolerance and dimension)!");
313 
314  // read in string, get double
315  if (params.size() > 0)
316  error_ = std::stod(params[0]);
317 
318  if (params.size() > 1) {
319  if (params[1] == "2D")
320  is_three_d_ = false;
321  else if (params[1] == "3D")
322  is_three_d_ = true;
323  else {
324  TEUCHOS_TEST_FOR_EXCEPTION(true,std::runtime_error,"ERROR: WedgeMatcher::parsParams() - the second params must be iether \"2D\" or \"3D\", param=" << params[1] << "\n");
325  }
326  }
327  }
328  WedgeMatcher(const WedgeMatcher & cm) = default;
329 
331  const Teuchos::Tuple<double,3> & b) const
332  {
333  if (is_three_d_) {
334  return ( (std::fabs(a[index0_]+b[index0_])<error_) &&
335  (std::fabs(a[1-index0_]-b[1-index0_])<error_) &&
336  (std::fabs(a[2]-b[2])<error_) );
337  }
338 
339  // else 2D
340  return ( (std::fabs(a[index0_]+b[index0_])<error_) &&
341  (std::fabs(a[1-index0_]-b[1-index0_])<error_) );
342  }
343 
344  std::string getString() const
345  {
346  std::stringstream ss;
347  if (index0_ == 0)
348  ss << "wy-coord <tol=" << error_ << ">";
349  else
350  ss << "wx-coord <tol=" << error_ << ">";
351  return ss.str();
352  }
353 
354  int getIndex() const {return index0_;}
355 
357  {
358  if (index0_ == 0)
359  return MirrorPlane::YZ_PLANE;
360  return MirrorPlane::XZ_PLANE;
361  }
362 
363  bool isThreeD() const {return is_three_d_;}
364 
365  double getAbsoluteTolerance() const {return error_;}
366 
367  void transform(double * ptB, const std::vector<double> & centroidA) const
368  {
369  // Instead of matching directly, shift pt B given the centroid
370  // of side A
371  // For now, we assume the wedge is mirrored over the yz or xz plane
372  // Then we just need to mirror over the plane
373 
374  ptB[index0_] = -ptB[index0_];
375 
376  return;
377  }
378 };
379 
380 } // end panzer_stk
381 
382 #endif
void transform(double *ptB, const std::vector< double > &centroidA) const
QuarterPlaneMatcher(int index0a, int index0b, int index1)
bool is_three_d_
Set to true if a 3D problem, set to false if 2D.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
WedgeMatcher::MirrorPlane getMirrorPlane() const
int index0_
index to compare - 0 for wy (mirrored over yz), 1 for wx (mirrored over xz)
CoordMatcher(int index, const std::vector< std::string > &params)
bool operator()(const Teuchos::Tuple< double, 3 > &a, const Teuchos::Tuple< double, 3 > &b) const
PlaneMatcher(int index0, int index1, const std::vector< std::string > &params)
void transform(double *ptB, const std::vector< double > &centroidA) const
bool operator()(const Teuchos::Tuple< double, 3 > &a, const Teuchos::Tuple< double, 3 > &b) const
void parseParams(const std::vector< std::string > &params)
bool operator()(const Teuchos::Tuple< double, 3 > &a, const Teuchos::Tuple< double, 3 > &b) const
void parseParams(const std::vector< std::string > &params)
QuarterPlaneMatcher(int index0a, int index0b, int index1, double error)
WedgeMatcher(MirrorPlane mp, const std::vector< std::string > &params)
CoordMatcher(int index)
index is the coordinate direction that will be compared to find matching nodes.
void parseParams(const std::vector< std::string > &params)
void transform(double *ptB, const std::vector< double > &centroidA) const
QuarterPlaneMatcher(int index0a, int index0b, int index1, const std::vector< std::string > &params)
bool operator()(const Teuchos::Tuple< double, 3 > &a, const Teuchos::Tuple< double, 3 > &b) const
#define TEUCHOS_ASSERT(assertion_test)
PlaneMatcher(int index0, int index1, double error)
void transform(double *ptB, const std::vector< double > &centroidA) const