gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
Particles.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #include <cmath>
7 #include "GmshConfig.h"
8 #include "Particles.h"
9 #include "OctreePost.h"
10 #include "Context.h"
11 #include "PViewOptions.h"
12 
13 #if defined(HAVE_OPENGL)
14 #include "drawContext.h"
15 #endif
16 
27  {GMSH_FULLRC, "NumPointsU", GMSH_ParticlesPlugin::callbackU, 10},
28  {GMSH_FULLRC, "NumPointsV", GMSH_ParticlesPlugin::callbackV, 1},
29  {GMSH_FULLRC, "A2", nullptr, 1.},
30  {GMSH_FULLRC, "A1", nullptr, 0.},
31  {GMSH_FULLRC, "A0", nullptr, 0.},
32  {GMSH_FULLRC, "DT", nullptr, .1},
33  {GMSH_FULLRC, "MaxIter", nullptr, 100},
34  {GMSH_FULLRC, "TimeStep", nullptr, 0},
35  {GMSH_FULLRC, "View", nullptr, -1.}};
36 
37 extern "C" {
39 {
40  return new GMSH_ParticlesPlugin();
41 }
42 }
43 
44 void GMSH_ParticlesPlugin::draw(void *context)
45 {
46 #if defined(HAVE_OPENGL)
47  glColor4ubv((GLubyte *)&CTX::instance()->color.fg);
48  drawContext *ctx = (drawContext *)context;
49  double p[3];
50  for(int i = 0; i < getNbU(); ++i) {
51  for(int j = 0; j < getNbV(); ++j) {
52  getPoint(i, j, p);
53  ctx->drawSphere(CTX::instance()->pointSize, p[0], p[1], p[2], 1);
54  }
55  }
56 #endif
57 }
58 
59 double GMSH_ParticlesPlugin::callback(int num, int action, double value,
60  double *opt, double step, double min,
61  double max)
62 {
63  switch(action) { // configure the input field
64  case 1: return step;
65  case 2: return min;
66  case 3: return max;
67  default: break;
68  }
69  *opt = value;
71  return 0.;
72 }
73 
74 double GMSH_ParticlesPlugin::callbackX0(int num, int action, double value)
75 {
76  return callback(num, action, value, &ParticlesOptions_Number[0].def,
77  CTX::instance()->lc / 100., -2 * CTX::instance()->lc,
78  2 * CTX::instance()->lc);
79 }
80 
81 double GMSH_ParticlesPlugin::callbackY0(int num, int action, double value)
82 {
83  return callback(num, action, value, &ParticlesOptions_Number[1].def,
84  CTX::instance()->lc / 100., -2 * CTX::instance()->lc,
85  2 * CTX::instance()->lc);
86 }
87 
88 double GMSH_ParticlesPlugin::callbackZ0(int num, int action, double value)
89 {
90  return callback(num, action, value, &ParticlesOptions_Number[2].def,
91  CTX::instance()->lc / 100., -2 * CTX::instance()->lc,
92  2 * CTX::instance()->lc);
93 }
94 
95 double GMSH_ParticlesPlugin::callbackX1(int num, int action, double value)
96 {
97  return callback(num, action, value, &ParticlesOptions_Number[3].def,
98  CTX::instance()->lc / 100., -2 * CTX::instance()->lc,
99  2 * CTX::instance()->lc);
100 }
101 
102 double GMSH_ParticlesPlugin::callbackY1(int num, int action, double value)
103 {
104  return callback(num, action, value, &ParticlesOptions_Number[4].def,
105  CTX::instance()->lc / 100., -2 * CTX::instance()->lc,
106  2 * CTX::instance()->lc);
107 }
108 
109 double GMSH_ParticlesPlugin::callbackZ1(int num, int action, double value)
110 {
111  return callback(num, action, value, &ParticlesOptions_Number[5].def,
112  CTX::instance()->lc / 100., -2 * CTX::instance()->lc,
113  2 * CTX::instance()->lc);
114 }
115 
116 double GMSH_ParticlesPlugin::callbackX2(int num, int action, double value)
117 {
118  return callback(num, action, value, &ParticlesOptions_Number[6].def,
119  CTX::instance()->lc / 100., -2 * CTX::instance()->lc,
120  2 * CTX::instance()->lc);
121 }
122 
123 double GMSH_ParticlesPlugin::callbackY2(int num, int action, double value)
124 {
125  return callback(num, action, value, &ParticlesOptions_Number[7].def,
126  CTX::instance()->lc / 100., -2 * CTX::instance()->lc,
127  2 * CTX::instance()->lc);
128 }
129 
130 double GMSH_ParticlesPlugin::callbackZ2(int num, int action, double value)
131 {
132  return callback(num, action, value, &ParticlesOptions_Number[8].def,
133  CTX::instance()->lc / 100., -2 * CTX::instance()->lc,
134  2 * CTX::instance()->lc);
135 }
136 
137 double GMSH_ParticlesPlugin::callbackU(int num, int action, double value)
138 {
139  return callback(num, action, value, &ParticlesOptions_Number[9].def, 1, 1,
140  100);
141 }
142 
143 double GMSH_ParticlesPlugin::callbackV(int num, int action, double value)
144 {
145  return callback(num, action, value, &ParticlesOptions_Number[10].def, 1, 1,
146  100);
147 }
148 
149 std::string GMSH_ParticlesPlugin::getHelp() const
150 {
151  return "Plugin(Particles) computes the trajectory "
152  "of particules in the force field given by the "
153  "`TimeStep'-th time step of a vector view "
154  "`View'.\n\n"
155  "The plugin takes as input a grid defined by the "
156  "3 points (`X0',`Y0',`Z0') (origin), (`X1',`Y1',`Z1') "
157  "(axis of U) and (`X2',`Y2',`Z2') (axis of V).\n\n"
158  "The number of particles along U and V that are to "
159  "be transported is set with the options `NumPointsU' "
160  "and `NumPointsV'. The equation\n\n"
161  "A2 * d^2X(t)/dt^2 + A1 * dX(t)/dt + A0 * X(t) = F\n\n"
162  "is then solved with the initial conditions X(t=0) "
163  "chosen as the grid, dX/dt(t=0)=0, and with F "
164  "interpolated from the vector view.\n\n"
165  "Time stepping is done using a Newmark scheme with "
166  "step size `DT' and `MaxIter' maximum number of "
167  "iterations.\n\n"
168  "If `View' < 0, the plugin is run on the current view.\n\n"
169  "Plugin(Particles) creates one new list-based view containing "
170  "multi-step vector points.";
171 }
172 
174 {
175  return sizeof(ParticlesOptions_Number) / sizeof(StringXNumber);
176 }
177 
179 {
180  return &ParticlesOptions_Number[iopt];
181 }
182 
184 {
185  return (int)ParticlesOptions_Number[9].def;
186 }
187 
189 {
190  return (int)ParticlesOptions_Number[10].def;
191 }
192 
193 void GMSH_ParticlesPlugin::getPoint(int iU, int iV, double *X)
194 {
195  double u = getNbU() > 1 ? (double)iU / (double)(getNbU() - 1.) : 0.;
196  double v = getNbV() > 1 ? (double)iV / (double)(getNbV() - 1.) : 0.;
197  X[0] = ParticlesOptions_Number[0].def +
199  v * (ParticlesOptions_Number[6].def - ParticlesOptions_Number[0].def);
200  X[1] = ParticlesOptions_Number[1].def +
202  v * (ParticlesOptions_Number[7].def - ParticlesOptions_Number[1].def);
203  X[2] = ParticlesOptions_Number[2].def +
205  v * (ParticlesOptions_Number[8].def - ParticlesOptions_Number[2].def);
206 }
207 
209 {
210  double A2 = ParticlesOptions_Number[11].def;
211  double A1 = ParticlesOptions_Number[12].def;
212  double A0 = ParticlesOptions_Number[13].def;
213  double DT = ParticlesOptions_Number[14].def;
214  int maxIter = (int)ParticlesOptions_Number[15].def;
215  int timeStep = (int)ParticlesOptions_Number[16].def;
216  int iView = (int)ParticlesOptions_Number[17].def;
217 
218  PView *v1 = getView(iView, v);
219  if(!v1) return v;
220  PViewData *data1 = getPossiblyAdaptiveData(v1);
221 
222  // sanity checks
223  if(timeStep > data1->getNumTimeSteps() - 1) {
224  Msg::Error("Invalid time step (%d) in view[%d]: using 0", v1->getIndex());
225  timeStep = 0;
226  }
227 
228  OctreePost o1(v1);
229 
230  PView *v2 = new PView();
231  PViewDataList *data2 = getDataList(v2);
232 
233  // solve 'A2 d^2x/dt^2 + A1 dx/dt + A0 x = F' using a Newmark scheme:
234  //
235  // (A2 + gamma DT A1 + beta DT^2 A0) x^{n+1} =
236  // (2 A2 - (1 - 2 gamma) DT A1 - (0.5 + gamma - 2 beta) DT^2 A0) x^n +
237  // (-A2 - (gamma - 1) DT A1 - (0.5 - gamma + beta) DT^2 A0) x^{n-1} +
238  // DT^2 (beta b^{n+1} + (0.5 + gamma - 2 beta) b^n + (0.5 - gamma + beta)
239  // b^{n-1})
240  //
241  // coefs for constant acceleration (unconditinonally stable)
242  const double gamma = 0.5, beta = 0.25;
243  double c1 = (A2 + gamma * DT * A1 + beta * DT * DT * A0);
244  double c2 = (2 * A2 - (1 - 2 * gamma) * DT * A1 -
245  (0.5 + gamma - 2 * beta) * DT * DT * A0);
246  double c3 =
247  (-A2 - (gamma - 1) * DT * A1 - (0.5 - gamma + beta) * DT * DT * A0);
248  double c4 =
249  DT * DT * (beta + (0.5 + gamma - 2 * beta) + (0.5 - gamma + beta));
250 
251  for(int i = 0; i < getNbU(); ++i) {
252  for(int j = 0; j < getNbV(); ++j) {
253  double XINIT[3], X0[3], X1[3];
254  getPoint(i, j, XINIT);
255  getPoint(i, j, X0);
256  getPoint(i, j, X1);
257  data2->NbVP++;
258  data2->VP.push_back(XINIT[0]);
259  data2->VP.push_back(XINIT[1]);
260  data2->VP.push_back(XINIT[2]);
261  for(int iter = 0; iter < maxIter; iter++) {
262  double F[3], X[3];
263  o1.searchVector(X1[0], X1[1], X1[2], F, timeStep);
264  for(int k = 0; k < 3; k++)
265  X[k] = (c2 * X1[k] + c3 * X0[k] + c4 * F[k]) / c1;
266  data2->VP.push_back(X[0] - XINIT[0]);
267  data2->VP.push_back(X[1] - XINIT[1]);
268  data2->VP.push_back(X[2] - XINIT[2]);
269  for(int k = 0; k < 3; k++) {
270  X0[k] = X1[k];
271  X1[k] = X[k];
272  }
273  }
274  }
275  }
276 
278 
279  data2->setName(data1->getName() + "_Particles");
280  data2->setFileName(data1->getName() + "_Particles.pos");
281  data2->finalize();
282 
283  return v2;
284 }
GMSH_ParticlesPlugin::getOption
StringXNumber * getOption(int iopt)
Definition: Particles.cpp:178
GMSH_RegisterParticlesPlugin
GMSH_Plugin * GMSH_RegisterParticlesPlugin()
Definition: Particles.cpp:38
PView
Definition: PView.h:27
ParticlesOptions_Number
StringXNumber ParticlesOptions_Number[]
Definition: Particles.cpp:17
GMSH_ParticlesPlugin::callbackZ0
static double callbackZ0(int, int, double)
Definition: Particles.cpp:88
Particles.h
GMSH_Plugin
Definition: Plugin.h:26
F
#define F
Definition: DefaultOptions.h:23
StringXNumber::def
double def
Definition: Options.h:922
PViewData::getNumTimeSteps
virtual int getNumTimeSteps()=0
OctreePost.h
PViewDataList
Definition: PViewDataList.h:17
GMSH_ParticlesPlugin::callbackU
static double callbackU(int, int, double)
Definition: Particles.cpp:137
GMSH_ParticlesPlugin::callbackX2
static double callbackX2(int, int, double)
Definition: Particles.cpp:116
GMSH_Plugin::draw
static void(* draw)(void *)
Definition: Plugin.h:77
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
GMSH_ParticlesPlugin
Definition: Particles.h:15
StringXNumber
Definition: Options.h:918
OctreePost
Definition: BoundaryLayers.cpp:23
PView::getIndex
int getIndex()
Definition: PView.h:92
GMSH_ParticlesPlugin::execute
PView * execute(PView *)
Definition: Particles.cpp:208
PViewData::setFileName
virtual void setFileName(const std::string &val)
Definition: PViewData.h:75
GMSH_ParticlesPlugin::callbackY1
static double callbackY1(int, int, double)
Definition: Particles.cpp:102
CTX::fg
unsigned int fg
Definition: Context.h:358
CTX::instance
static CTX * instance()
Definition: Context.cpp:122
GMSH_ParticlesPlugin::callbackZ1
static double callbackZ1(int, int, double)
Definition: Particles.cpp:109
GMSH_ParticlesPlugin::callbackX0
static double callbackX0(int, int, double)
Definition: Particles.cpp:74
PViewDataList::VP
std::vector< double > VP
Definition: PViewDataList.h:27
GMSH_ParticlesPlugin::callbackZ2
static double callbackZ2(int, int, double)
Definition: Particles.cpp:130
GMSH_FULLRC
#define GMSH_FULLRC
Definition: Options.h:20
GMSH_ParticlesPlugin::callbackY0
static double callbackY0(int, int, double)
Definition: Particles.cpp:81
PViewOptions.h
GMSH_ParticlesPlugin::callback
static double callback(int num, int action, double value, double *opt, double step, double min, double max)
Definition: Particles.cpp:59
drawContext
Definition: drawContext.h:120
GMSH_ParticlesPlugin::callbackV
static double callbackV(int, int, double)
Definition: Particles.cpp:143
PViewDataList::finalize
bool finalize(bool computeMinMax=true, const std::string &interpolationScheme="")
Definition: PViewDataList.cpp:81
PViewData::setName
virtual void setName(const std::string &val)
Definition: PViewData.h:71
PViewOptions::Displacement
@ Displacement
Definition: PViewOptions.h:25
GMSH_ParticlesPlugin::getPoint
static void getPoint(int iU, int iV, double *X)
Definition: Particles.cpp:193
GMSH_ParticlesPlugin::getNbV
static int getNbV()
Definition: Particles.cpp:188
PViewDataList::NbVP
int NbVP
Definition: PViewDataList.h:26
PViewData
Definition: PViewData.h:29
GMSH_ParticlesPlugin::callbackX1
static double callbackX1(int, int, double)
Definition: Particles.cpp:95
GMSH_ParticlesPlugin::getNbU
static int getNbU()
Definition: Particles.cpp:183
Context.h
OctreePost::searchVector
bool searchVector(double x, double y, double z, double *values, int step=-1, double *size=nullptr, int qn=0, double *qx=nullptr, double *qy=nullptr, double *qz=nullptr, bool grad=false, int dim=-1)
Definition: OctreePost.cpp:634
GMSH_ParticlesPlugin::getNbOptions
int getNbOptions() const
Definition: Particles.cpp:173
GMSH_Plugin::setDrawFunction
static void setDrawFunction(void(*fct)(void *))
Definition: Plugin.cpp:21
GMSH_PostPlugin::getView
virtual PView * getView(int index, PView *view)
Definition: Plugin.cpp:81
GMSH_PostPlugin::getPossiblyAdaptiveData
virtual PViewData * getPossiblyAdaptiveData(PView *view)
Definition: Plugin.cpp:94
PView::getOptions
PViewOptions * getOptions()
Definition: PView.h:81
PViewOptions::vectorType
int vectorType
Definition: PViewOptions.h:60
PViewData::getName
virtual std::string getName()
Definition: PViewData.h:70
GMSH_ParticlesPlugin::getHelp
std::string getHelp() const
Definition: Particles.cpp:149
c1
const double c1
Definition: GaussQuadratureHex.cpp:16
drawContext::drawSphere
void drawSphere(double R, double x, double y, double z, int n1, int n2, int light)
Definition: drawGlyph.cpp:390
GMSH_ParticlesPlugin::callbackY2
static double callbackY2(int, int, double)
Definition: Particles.cpp:123
GMSH_PostPlugin::getDataList
virtual PViewDataList * getDataList(PView *view, bool showError=true)
Definition: Plugin.cpp:107
DT
Definition: DivideAndConquer.h:50
drawContext.h