Free Electron
SemiImplicit1D.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2021 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #ifndef __solve_SemiImplicit1D_h__
8 #define __solve_SemiImplicit1D_h__
9 
10 #include "signal/signal.h"
11 #include "datatool/datatool.h"
12 #include "shape/shape.h"
13 
14 #define PARTICLE_DEBUG
15 //#define USE_FILTERS
16 
17 /**
18 
19 @page semiimplicit_1d_solver 1D solver
20 
21 One main use case for this solver is for mechanical rotational systems.
22 However, the language of this solver is in simple clumped mass system
23 terminology. So, in the interface you see "particle", "mass", "velocity",
24 and "force".
25 When using this for a mechanical rotational system, you can think of these
26 as "shaft", "moment of inertia", "angular velocity", and "torque".
27 The solve math is equivalent.
28 
29 The main thing this solver has beyond a simple clumped mass solver to support
30 mechanical rotational systems is the idea of ratios. Every "mass" (or shaft)
31 has a ratio for which it "spins" from the point of view of a use case, that
32 may differ from the point of view of the numerical solve. The reason for this
33 is that the numerical solver can only solver in a single "spin space" for
34 all connected shafts.
35 
36 Ratio groups ...
37 
38 @verbatim
39 
40 simple example
41 
42 shaft <-> gear <-> shaft <-> clutch <-> shaft
43  | | | |
44  | <--- pair ---> | <--- pair ---> |
45  | | |
46  mass <-----------> mass <-------------> mass
47  | \ /
48  | \ /
49 ratio group ratio group
50 
51 @endverbatim
52 
53 Conversion functions when operating with ratios as a mechanical rotational
54 system.
55 
56 Functions that convert values from ??? solver space to user space:
57  - l_ext -- Linear (postion) rad
58  - v_ext -- angular Velocity rad/s
59  - f_ext -- torque (Force) Nm
60  - k_ext -- stiffness (K) Nm/rad
61  - d_ext -- Damping/Drag (viscous) Nm/rad/s
62 
63 Functions that convert values from user space to solver space:
64  - m_int -- moment of inertia (Mass) kgm
65 
66 
67 connect ratio into pairs?
68 
69 ACCUM GUIDE
70 
71 USER | SOLVER
72 params ---- ext ------------>
73  force
74 
75 
76 
77 compile
78  precompile (add more particles into data)
79  process dataset to create sim particles and constraints
80  pairs
81  process dataset to create collector sparse matrix, connectivity groups, etc, from pairs info
82  compile (populate sparse matrix with entries necessary to accumulate)
83  bake/optimize solver sparse matrix using collector sparse matrix
84  reconfigure (run time dynamic change of configuration (parameters, etc)) in particular, ratios
85 
86 
87 step
88  accumulate
89 
90 validate
91 
92 reconfigure
93  reconfigure
94  bake ratios in pairs down to solver per-shaft ratios.
95 
96 ratios
97  per shaft for solve
98  per pair
99 
100 */
101 
102 namespace fe
103 {
104 namespace ext
105 {
106 
107 inline t_solve_real l_ext(t_solve_real a_value, t_solve_real a_ratio)
108 {
109  return a_value / a_ratio;
110 }
111 inline t_solve_real v_ext(t_solve_real a_value, t_solve_real a_ratio)
112 {
113  return a_value / a_ratio;
114 }
115 inline t_solve_real f_ext(t_solve_real a_value, t_solve_real a_ratio)
116 {
117  return a_value * a_ratio;
118 }
119 inline t_solve_real k_ext(t_solve_real a_value, t_solve_real a_ratio)
120 {
121  return a_value * a_ratio * a_ratio;
122 }
123 inline t_solve_real d_ext(t_solve_real a_value, t_solve_real a_ratio)
124 {
125  return a_value * a_ratio * a_ratio;
126 }
127 inline t_solve_real m_int_deprecate(t_solve_real a_mass, t_solve_real a_ratio)
128 {
129  return a_mass * a_ratio * a_ratio;
130 }
131 
132 
133 // these seem unnecessary, and tempt bugs
134 #if 0
135 inline t_solve_real l_int(t_solve_real a_value, t_solve_real a_ratio)
136 {
137  return a_value * a_ratio;
138 }
139 inline t_solve_real v_int(t_solve_real a_value, t_solve_real a_ratio)
140 {
141  return a_value * a_ratio;
142 }
143 
144 inline t_solve_real f_int(t_solve_real a_value, t_solve_real a_ratio)
145 {
146  return a_value / a_ratio;
147 }
148 #endif
149 
150 /** Semi Implicit time integration
151 
152  @copydoc SemiImplicit1D_info
153  */
154 class FE_DL_EXPORT SemiImplicit1D : public Handled<SemiImplicit1D>
155 {
156  public:
157  SemiImplicit1D(void);
158 virtual ~SemiImplicit1D(void);
159 
160 virtual void compile(sp<RecordGroup> rg_input);
161 virtual void initialize(sp<Scope> a_spScope);
162 virtual void extract(sp<RecordGroup> rg_output);
163 virtual void step(t_solve_real a_timestep, t_solve_real &a_totalConstraintForce);
164 
165 virtual void setRayleighDamping(bool a_flag) { m_rayleigh_damping = a_flag; }
166 virtual void setRayleighDamping(t_solve_real a_stiffness, t_solve_real a_mass)
167  {
168  m_rayleigh_stiffness = a_stiffness;
169  m_rayleigh_mass = -a_mass;
170  }
171 
172 virtual void shiftDomain(t_solve_real a_period, unsigned int a_p);
173 virtual void shiftDomain(void);
174 
175  void reset(void);
176 
177  void propogateRatiosFrom(unsigned int a_p);
178 
179 
180  void reconfigure(void);
181 
182 
183 
184  typedef unsigned int t_size;
185  class t_pair : public Counted
186  {
187  public:
188  friend SemiImplicit1D;
189  t_pair(void)
190  {
191  m_ratio = 1.0;
192  }
193  t_pair(const t_size &a_first, const t_size &a_second)
194  {
195  first = a_first;
196  second = a_second;
197  m_ratio = 1.0;
198  }
199  void setGearRatio(int a_from, int a_to)
200  {
201  if (a_from < 1) { a_from = 1; }
202  if (a_to < 1) { a_to = 1; }
203  m_ratio = (t_solve_real)a_from/(t_solve_real)a_to;
204  }
205  /// This likely screws up any viable domain shifting
206  void setIrrational(t_solve_real a_maybe_irrational)
207  {
208  m_ratio = a_maybe_irrational;
209  }
210 
211 
212  t_size first; // syntax to match std::pair
213  t_size second; // syntax to match std::pair
214  private:
215  t_solve_real m_ratio;
216  };
217  typedef std::vector< fe::sp<t_pair> > t_pairs;
218 
219 
220  class Particle
221  {
222  public:
223  t_solve_real m_location;
224  t_solve_real m_adjustment;
225  t_solve_real m_velocity;
226  t_solve_real m_force;
227  t_solve_real m_force_weak;
228  t_solve_real m_force_external;
229  t_solve_real m_mass;
230  t_solve_real m_prev_location;
231  t_solve_real m_prev_velocity;
232  t_solve_real m_constraint_force;
233 
234  t_solve_real m_ratio;
235  // correct location upon changing ratios needs to be integrated on its own
236  t_solve_real m_location_ratio;
237  bool m_adjustable;
238  bool m_shift_root;
239 
240  t_pairs m_pairs;
241 
242 #ifdef PARTICLE_DEBUG
243  Color m_color;
244 #endif
245  };
246 
247  std::vector<Particle> &particles(void) { return m_particles; }
248  bool lookupIndex(unsigned int &a_particle, Record &r_particle);
249 
250  class FE_DL_EXPORT CompileMatrix
251  {
252  public:
253  CompileMatrix(void);
254  ~CompileMatrix(void);
255 
256  typedef t_solve_real **t_ppBlock;
257  typedef std::vector<t_ppBlock> t_dfdx_array;
258  typedef std::vector<t_ppBlock> t_dfdv_array;
259  typedef std::pair<t_dfdx_array, t_dfdv_array> t_entry;
260  typedef std::map<unsigned int, t_entry> t_row;
261 
262  std::vector<t_row> m_rows;
263 
264  void clear(void);
265  void setRows(unsigned int a_count);
266  unsigned int rows(void);
267  t_row &row(unsigned int a_index);
268  t_entry &entry( unsigned int a_i,
269  unsigned int a_j);
270 
271  typedef std::set<unsigned int> t_nonzero_set;
272  typedef std::vector< t_nonzero_set > t_nonzero_pattern;
273 
274  void symbolicFill(void);
275  };
276 
277  typedef std::vector< std::vector<unsigned int> > t_shift;
278  typedef std::vector< std::vector<unsigned int> > t_neighbors;
279  class Force : public Counted, public fe::CastableAs<Force>
280  {
281  public:
282  Force(void){ m_timestep = 0.0; }
283  virtual ~Force(void){}
284 
285  //virtual void clear(void){}
286  virtual void accumulate(void) = 0;
287  virtual bool validate(void){ return true; }
288 
289  virtual void compile( sp<RecordGroup> rg_input,
290  std::vector<Particle> &a_particles,
291  CompileMatrix &a_compileMatrix){}
292  virtual void precompile(sp<RecordGroup> rg_input) {}
293  virtual void pairs( sp<RecordGroup> rg_input,
294  t_pairs &a_pairs) { }
295  void setTimestep(t_solve_real a_timestep) { m_timestep = a_timestep; }
296  virtual void reconfigure(void) {}
297  protected:
298  t_solve_real m_timestep;
299  };
300 
301 virtual void addForce(sp<Force> a_force, bool a_add_damping=false);
302 
303 
304 
305  private:
306  t_solve_real m_int(t_solve_real a_mass, t_solve_real a_ratio)
307  {
308  return a_mass * a_ratio * a_ratio;
309  }
310 
311  void reorder(std::vector<unsigned int> &a_order, t_pairs &a_pairs);
312 
313  std::vector<Particle> m_particles;
314 
315  AsParticle1D m_asParticle;
316  AsSolverParticle1D m_asSolverParticle;
317  AsComponent m_asComponent;
318  AsForcePoint1D m_asForcePoint;
319  AsTemporal m_asTemporal;
320  AsValidate m_asValidate;
321  AsAccumulate m_asAccumulate;
322  AsClear m_asClear;
323  AsUpdate m_asUpdate;
324 #ifdef PARTICLE_DEBUG
325  AsColored m_asColored;
326 #endif
327  AsForceFilter m_asForceFilter;
328  hp<SignalerI> m_hpSignaler;
329 
330  unsigned int m_n;
331  unsigned int m_n_sim;
332  std::vector< sp<Force> > m_forces_add_damping;
333  std::vector< sp<Force> > m_forces_as_is;
334 
335  t_solve_real m_dummy_block;
336 
341 
342  std::vector<t_solve_real> m_rhs;
343  std::vector<t_solve_real> m_dv;
344  std::vector<t_solve_real> m_tmp;
345 
346 
347  std::map<FE_UWORD, unsigned int> m_recordToParticle;
348 
349  t_solve_real m_dv2dxRatio;
350  t_solve_real m_dxImplicitness;
351  t_solve_real m_dvImplicitness;
352 
353  unsigned int m_subdivcnt;
354  unsigned int m_subdivsz;
355  t_solve_real m_subdivmult;
356 
357  bool m_rayleigh_damping;
358  t_solve_real m_rayleigh_stiffness;
359  t_solve_real m_rayleigh_mass;
360  std::vector<t_solve_real> m_perturb;
361 
362  std::vector<t_solve_real> m_adjustableState;
363 
364  t_shift m_shift;
365 };
366 
367 } /* namespace */
368 } /* namespace */
369 
370 
371 #endif /* __solve_SemiImplicit1D_h__ */
372 
just a Component
Definition: AccessorSets.h:92
Heap-based support for classes participating in fe::ptr <>
Definition: Counted.h:35
kernel
Definition: namespace.dox:3
clear signal
Definition: solveAS.h:38
Special vector for color (RGBA)
Definition: Color.h:21
force application point
Definition: shapeAS.h:98
Semi Implicit time integration.
Definition: SemiImplicit1D.h:154
Time-based Operator.
Definition: datatoolAS.h:73
validate signal
Definition: solveAS.h:80
update state signal
Definition: solveAS.h:97
Reference to an instance of a Layout.
Definition: RecordSB.h:35
particle in physical space
Definition: shapeAS.h:114
Base class providing an fe::Handle to the derived class.
Definition: Handled.h:209
accumulate signal
Definition: solveAS.h:59
Per-class participation non-RTTI fallback dynamic casting mechanism.
Definition: Castable.h:192