G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsAPALM.h
Go to the documentation of this file.
1
14#pragma once
15
17#include <gsIO/gsOptionList.h>
20
21#include <gsParallel/gsMpi.h>
22
23namespace gismo
24{
25
26#define gsMPIInfo(rank) gsInfo<<"[MPI process "<<rank<<"]: "
27#define gsMPIDebug(rank) gsDebug<<"[MPI process "<<rank<<"]: "
28
29/*
30 * IDEA (Hugo Verhelst, 03-03-2023):
31 * The APALM can be extended for adaptive meshes by storing multipatches as solutions.
32 * Starting from a solution (i.e. a mp), one can construct the start point vector internally
33 * and continue with 'normal' arclength methods. The distance function for the ALM
34 * can be re-implemented for multipatches if needed. The major changes will be that the
35 * parts where gsALMBase::step() is called need to be specialized.
36 */
37
38template<class T>
39class gsAPALM
40{
41
42public:
43 typedef typename std::pair<gsVector<T>,T> solution_t;
44
45 virtual ~gsAPALM()
46 {
47 if (m_comm_dummy)
48 delete m_comm_dummy;
49 }
50
58#ifdef GISMO_WITH_MPI
59 gsAPALM( gsALMBase<T> * ALM,
60 const gsAPALMData<T,solution_t> & Data,
61 const gsMpiComm & comm );
62#else
63 gsAPALM( gsALMBase<T> * ALM,
64 const gsAPALMData<T,solution_t> & Data,
65 const gsSerialComm & comm );
66#endif
73 gsAPALM( gsALMBase<T> * ALM,
74 const gsAPALMData<T,solution_t> & Data);
75
79 gsAPALM()
80 :
81#ifdef GISMO_WITH_MPI
82 m_comm_dummy(new gsMpiComm()),
83#else
84 m_comm_dummy(new gsSerialComm()),
85#endif
86 m_comm(*m_comm_dummy)
87 {
88
89
90 };
91
92private:
93
94 virtual void _defaultOptions();
95
96 virtual void _getOptions();
97
98 void _initStart(const gsVector<T> & Ustart, const T & Lstart, const T & dL);
99 void _initStart(const std::vector<gsVector<T>> & Ustart, const std::vector<T> & Lstart, const std::vector<T> & dLs);
100
101public:
105 virtual void initialize();
106
112 virtual void solve(index_t Nsteps = 10);
118 virtual void serialSolve(index_t Nsteps = 10);
122 virtual void parallelSolve();
123
131 virtual void serialStepOutput(const std::pair<gsVector<T>,T> & /*pair*/, const T & /*time*/, index_t /*step*/) {};
139 virtual void parallelStepOutput(const std::pair<gsVector<T>,T> & /*pair*/, const T & /*time*/, index_t /*step*/) {};
148 virtual void parallelIntervalOutput(const std::vector<std::pair<gsVector<T>,T>> & /*stepSolutions*/, const std::vector<T> & /*stepTimes*/, index_t /*level*/, index_t /*ID*/) {};
149
155 gsOptionList & options() { return m_options; }
156
162 const gsAPALMDataContainer<T,solution_t> & getHierarchy() const { return m_data; }
163 gsAPALMDataContainer<T,solution_t> getHierarchy() { return m_data; }
164
172 const std::vector<solution_t> & getFlatSolutions(index_t branch = 0) const { return m_solutions[branch]; }
173 std::vector<solution_t> getFlatSolutions(index_t branch = 0) { return m_solutions[branch]; }
174
182 const std::vector<T> & getFlatTimes(index_t branch = 0) const { return m_times[branch]; }
183 std::vector<T> getFlatTimes(index_t branch = 0) { return m_times[branch]; }
184
192 const std::vector<index_t> & getFlatLevels(index_t branch = 0) const { return m_levels[branch]; }
193 std::vector<index_t> getFlatLevels(index_t branch = 0) { return m_levels[branch]; }
194
203 const std::vector<solution_t *> & getSolutions(index_t level, index_t branch = 0) const { return m_lvlSolutions[branch][level]; }
204 std::vector<solution_t> getSolutions(index_t level, index_t branch = 0)
205 {
206 std::vector<solution_t> result;
207 for (typename std::vector<solution_t *>::iterator it=m_lvlSolutions[branch][level].begin(); it!=m_lvlSolutions[branch][level].end(); it++)
208 result.push_back(**it);
209 return result;
210 }
211
219 std::vector<std::vector<solution_t>> getSolutionsPerLevel(index_t branch = 0)
220 {
221 std::vector<std::vector<solution_t>> result(m_lvlSolutions[branch].size());
222 for (size_t l=0; l!=m_lvlSolutions[branch].size(); l++)
223 for (typename std::vector<solution_t *>::iterator it=m_lvlSolutions[branch][l].begin(); it!=m_lvlSolutions[branch][l].end(); it++)
224 result[l].push_back(**it);
225 return result;
226 }
227
228
237 const std::vector<T *> & getTimes(index_t level, index_t branch = 0) const { return m_lvlTimes[branch][level]; }
238 std::vector<T> getTimes(index_t level, index_t branch = 0)
239 {
240 std::vector<T> result;
241 for (typename std::vector<T *>::iterator it=m_lvlTimes[branch][level].begin(); it!=m_lvlTimes[branch][level].end(); it++)
242 result.push_back(**it);
243 return result;
244 }
245
253 std::vector<std::vector<T>> getTimesPerLevel(index_t branch = 0)
254 {
255 std::vector<std::vector<T>> result(m_lvlTimes[branch].size());
256 for (size_t l=0; l!=m_lvlSolutions[branch].size(); l++)
257 for (typename std::vector<T *>::iterator it=m_lvlTimes[branch][l].begin(); it!=m_lvlTimes[branch][l].end(); it++)
258 result[l].push_back(**it);
259 return result;
260 }
261
262#ifdef GISMO_WITH_MPI
263
269 bool isMain() {return (m_rank==0); }
270
276 index_t rank() {return (m_rank); }
277
283 index_t size() { return m_proc_count; };
284
285#else
286 bool isMain() {return true; }
287 index_t rank() {return 0; }
288 index_t size() {return 1; }
289#endif
290
291protected:
292
293#ifdef GISMO_WITH_MPI
294 // For meta-data
295 void _sendMainToWorker( const index_t & workerID,
296 const index_t & branch,
297 const index_t & jobID,
298 const index_t & dataLevel);
299
300 // For data
301 void _sendMainToWorker( const index_t & workerID,
302 const std::tuple<index_t, T , solution_t, solution_t> & dataEntry,
303 const std::pair<T,T> & dataInterval,
304 const solution_t & dataReference );
305
306 void _sendMainToWorker( const index_t & workerID,
307 const std::tuple<index_t, T , solution_t, solution_t> & dataEntry,
308 const T & startTime);
309 // For stop signal
310 void _sendMainToWorker( const index_t & workerID,
311 const bool & stop );
312 void _sendMainToAll( const bool & stop );
313
314 // For meta-data
315 void _recvMainToWorker( const index_t & sourceID,
316 index_t & branch,
317 index_t & jobID,
318 index_t & dataLevel);
319
320 // For data
321 void _recvMainToWorker( const index_t & sourceID,
322 std::tuple<index_t, T , solution_t, solution_t> & dataEntry,
323 std::pair<T,T> & dataInterval,
324 solution_t & dataReference);
325
326 void _recvMainToWorker( const index_t & sourceID,
327 std::tuple<index_t, T , solution_t, solution_t> & dataEntry,
328 T & startTime);
329
330 // For stop signal
331 void _recvMainToWorker( const index_t & sourceID,
332 bool & stop);
333 // For meta-data
334 void _sendWorkerToMain( const index_t & mainID,
335 const index_t & branch,
336 const index_t & jobID);
337
338 // For meta-data
339 void _recvWorkerToMain( index_t & sourceID, // source ID will change to MPI
340 index_t & branch,
341 index_t & jobID);
342 // For data
343 void _sendWorkerToMain( const index_t & mainID,
344 const std::vector<T> & distances,
345 const std::vector<solution_t> & stepSolutions,
346 const T & upperDistance,
347 const T & lowerDistance );
348
349 void _sendWorkerToMain( const index_t & mainID,
350 const T & distance,
351 const std::vector<solution_t> & solutions,
352 const bool & bifurcation);
353
354 // For data
355 void _recvWorkerToMain( index_t & sourceID, // source ID will change to MPI
356 std::vector<T> & distances,
357 std::vector<solution_t>& stepSolutions,
358 T & upperDistance,
359 T & lowerDistance);
360
361 void _recvWorkerToMain( index_t & sourceID, // source ID will change to MPI
362 T & distance,
363 std::vector<solution_t> & stepSolutions,
364 bool & bifurcation);
365
366#endif
367
368#ifdef GISMO_WITH_MPI
369 const gsMpiComm & comm() { return m_comm; }
370#else
371 const gsSerialComm & comm() { return m_comm; }
372#endif
373
374 template <bool _hasWorkers>
375 typename std::enable_if< _hasWorkers, void>::type
376 _solve_impl(index_t Nsteps);
377
378 template <bool _hasWorkers>
379 typename std::enable_if<!_hasWorkers, void>::type
380 _solve_impl(index_t Nsteps);
381
382 template <bool _hasWorkers>
383 typename std::enable_if< _hasWorkers, void>::type
384 parallelSolve_impl();
385
386 template <bool _hasWorkers>
387 typename std::enable_if<!_hasWorkers, void>::type
388 parallelSolve_impl();
389
390 void _initiation( const std::tuple<index_t, T , solution_t, solution_t> & dataEntry,
391 const T & startTime,
392 T & endTime,
393 std::vector<solution_t>&solutions,
394 bool & bifurcation );
395
396 void _correction( const std::tuple<index_t, T , solution_t, solution_t> & dataEntry,
397 const std::pair<T,T> & dataInterval,
398 const index_t & dataLevel,
399 const solution_t & dataReference,
400 std::vector<T> & distances,
401 std::vector<solution_t>&stepSolutions,
402 T & upperDistance,
403 T & lowerDistance );
404
405 void _finalize();
406
407protected:
408
409 std::vector<std::vector<solution_t>> m_solutions;
410 std::vector<std::vector<T>> m_times;
411 std::vector<std::vector<index_t>> m_levels;
412
413 std::queue<std::tuple<solution_t,T,bool>> m_starts; // solution, step length, true if start was a bifurcation
414
415 std::vector<std::vector<std::vector<solution_t * > > > m_lvlSolutions;
416 std::vector<std::vector<std::vector<T * > > > m_lvlTimes;
417
418 gsALMBase<T> * m_ALM;
419 gsAPALMData<T,solution_t> m_dataEmpty;
420 gsAPALMDataContainer<T,solution_t> m_data;
421
422 bool m_verbose;
423 index_t m_subIntervals;
424
425 gsOptionList m_options;
426
427 bool m_singularPoint;
428 T m_branchLengthMult;
429 T m_bifLengthMult;
430
431 index_t m_maxIterations;
432
433 // Conditional compilation
434#ifdef GISMO_WITH_MPI
435 const gsMpiComm * m_comm_dummy = nullptr;
436 const gsMpiComm & m_comm;
437 std::queue<index_t> m_workers;
438#else
439 const gsSerialComm * m_comm_dummy = nullptr;
440 const gsSerialComm & m_comm;
441#endif
442
443
444 index_t m_proc_count, m_rank;
445};
446
447}
448
449#ifndef GISMO_BUILD_LIB
450#include GISMO_HPP_HEADER(gsAPALM.hpp)
451#endif
Base class to perform the arc length method to solve a nonlinear equation system.
Performs the arc length method to solve a nonlinear equation system.
#define index_t
Definition gsConfig.h:32
This is the main header file that collects wrappers of Eigen for linear algebra.
Helpers for dealing with MPI codes.
Provides a list of labeled parameters/options that can be set and accessed easily.
The G+Smo namespace, containing all definitions for the library.
T distance(gsMatrix< T > const &A, gsMatrix< T > const &B, index_t i=0, index_t j=0, bool cols=false)
compute a distance between the point number in the set and the point number <j> in the set ; by def...