Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/Inciter/OversetFE.hpp
4 : : \copyright 2012-2015 J. Bakosi,
5 : : 2016-2018 Los Alamos National Security, LLC.,
6 : : 2019-2021 Triad National Security, LLC.
7 : : All rights reserved. See the LICENSE file for details.
8 : : \brief OversetFE for a PDE system with continuous Galerkin FE + RK
9 : : \details OversetFE advances a system of partial differential equations
10 : : using a continuous Galerkin (CG) finite element (FE) spatial discretization
11 : : (using linear shapefunctions on tetrahedron elements) combined with a
12 : : Runge-Kutta (RK) time stepping scheme and overset grids.
13 : :
14 : : There are a potentially large number of OversetFE Charm++ chares created by
15 : : Transporter. Each OversetFE gets a chunk of the full load (part of the mesh)
16 : : and does the same: initializes and advances a number of PDE systems in time.
17 : :
18 : : The implementation uses the Charm++ runtime system and is fully
19 : : asynchronous, overlapping computation and communication. The algorithm
20 : : utilizes the structured dagger (SDAG) Charm++ functionality.
21 : : */
22 : : // *****************************************************************************
23 : : #ifndef OversetFE_h
24 : : #define OversetFE_h
25 : :
26 : : #include <vector>
27 : : #include <map>
28 : :
29 : : #include "Types.hpp"
30 : : #include "Fields.hpp"
31 : : #include "Table.hpp"
32 : : #include "DerivedData.hpp"
33 : : #include "NodeDiagnostics.hpp"
34 : : #include "Ghosts.hpp"
35 : :
36 : : #include "NoWarning/oversetfe.decl.h"
37 : :
38 : : namespace inciter {
39 : :
40 : : //! OversetFE Charm++ chare array used to advance PDEs in time with OversetFE+RK
41 : : class OversetFE : public CBase_OversetFE {
42 : :
43 : : public:
44 : : #if defined(__clang__)
45 : : #pragma clang diagnostic push
46 : : #pragma clang diagnostic ignored "-Wunused-parameter"
47 : : #pragma clang diagnostic ignored "-Wdeprecated-declarations"
48 : : #elif defined(STRICT_GNUC)
49 : : #pragma GCC diagnostic push
50 : : #pragma GCC diagnostic ignored "-Wunused-parameter"
51 : : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
52 : : #elif defined(__INTEL_COMPILER)
53 : : #pragma warning( push )
54 : : #pragma warning( disable: 1478 )
55 : : #endif
56 : : // Include Charm++ SDAG code. See http://charm.cs.illinois.edu/manuals/html/
57 : : // charm++/manual.html, Sec. "Structured Control Flow: Structured Dagger".
58 : : OversetFE_SDAG_CODE
59 : : #if defined(__clang__)
60 : : #pragma clang diagnostic pop
61 : : #elif defined(STRICT_GNUC)
62 : : #pragma GCC diagnostic pop
63 : : #elif defined(__INTEL_COMPILER)
64 : : #pragma warning( pop )
65 : : #endif
66 : :
67 : : //! Constructor
68 : : explicit OversetFE( const CProxy_Discretization& disc,
69 : : const CProxy_Ghosts& ghostsproxy,
70 : : const std::map< int, std::vector< std::size_t > >& bface,
71 : : const std::map< int, std::vector< std::size_t > >& bnode,
72 : : const std::vector< std::size_t >& triinpoel );
73 : :
74 : : #if defined(__clang__)
75 : : #pragma clang diagnostic push
76 : : #pragma clang diagnostic ignored "-Wundefined-func-template"
77 : : #endif
78 : : //! Migrate constructor
79 : : // cppcheck-suppress uninitMemberVar
80 : 978 : explicit OversetFE( CkMigrateMessage* msg ) : CBase_OversetFE( msg ) {}
81 : : #if defined(__clang__)
82 : : #pragma clang diagnostic pop
83 : : #endif
84 : :
85 : : //! Configure Charm++ custom reduction types initiated from this chare array
86 : : static void registerReducers();
87 : :
88 : : //! Return from migration
89 : : void ResumeFromSync() override;
90 : :
91 : : //! Start setup for solution
92 : : void setup();
93 : :
94 : : //! Receive total box IC volume and set conditions in box
95 : : void box( tk::real v, const std::vector< tk::real >& blkvols );
96 : :
97 : : //! Transfer solution to other solver and mesh if coupled
98 : : void transferSol();
99 : :
100 : : // Start time stepping
101 : : void start();
102 : :
103 : : //! Advance equations to next time step
104 : : void advance( tk::real newdt, tk::real nmovedmesh );
105 : :
106 : : //! Compute left-hand side of transport equations
107 : : void lhs();
108 : :
109 : : //! Receive contributions to duual-face normals on chare boundaries
110 : : void comdfnorm(
111 : : const std::unordered_map< tk::UnsMesh::Edge,
112 : : std::array< tk::real, 3 >,
113 : : tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> >& dfnorm );
114 : :
115 : : //! Receive boundary point normals on chare-boundaries
116 : : void comnorm( const std::unordered_map< int,
117 : : std::unordered_map< std::size_t, std::array< tk::real, 4 > > >& innorm );
118 : :
119 : : //! Receive mesh block information for nodes on chare-boundaries
120 : : void comblk( const std::vector< std::size_t >& gid,
121 : : const std::vector< std::set< std::size_t > >& mb );
122 : :
123 : : //! Receive contributions to gradients on chare-boundaries
124 : : void comChBndGrad( const std::vector< std::size_t >& gid,
125 : : const std::vector< std::vector< tk::real > >& G );
126 : :
127 : : //! Receive contributions to right-hand side vector on chare-boundaries
128 : : void comrhs( const std::vector< std::size_t >& gid,
129 : : const std::vector< std::vector< tk::real > >& R );
130 : :
131 : : //! Update solution at the end of time step
132 : : void update( const tk::Fields& a );
133 : :
134 : : //! Optionally refine/derefine mesh
135 : : void refine( const std::vector< tk::real >& l2res );
136 : :
137 : : //! Extract field output to file
138 : : void extractFieldOutput(
139 : : const std::vector< std::size_t >& /* ginpoel */,
140 : : const tk::UnsMesh::Chunk& /*chunk*/,
141 : : const tk::UnsMesh::Coords& /*coord*/,
142 : : const std::unordered_map< std::size_t, tk::UnsMesh::Edge >& /* addedNodes */,
143 : : const std::unordered_map< std::size_t, std::size_t >& /*addedTets*/,
144 : : const tk::NodeCommMap& /*nodeCommMap*/,
145 : : const std::map< int, std::vector< std::size_t > >& /*bface*/,
146 : : const std::map< int, std::vector< std::size_t > >& /* bnode */,
147 : : const std::vector< std::size_t >& /*triinpoel*/,
148 : : CkCallback /*c*/ ) {}
149 : :
150 : : //! Const-ref access to current solution
151 : : //! \return Const-ref to current solution
152 : : const tk::Fields& solution() const { return m_u; }
153 : :
154 : : //! Evaluate whether to continue with next time step
155 : : void step();
156 : :
157 : : // Evaluate whether to do load balancing
158 : : void evalLB( int nrestart );
159 : :
160 : : //! Evaluate whether to continue with next time step stage
161 : : void stage();
162 : :
163 : : //! Continue to next time step
164 : : void next();
165 : :
166 : : //! Size communication buffers (no-op)
167 : : void resizeComm() {}
168 : :
169 : : //! Setup node-neighborhood (no-op)
170 : : void nodeNeighSetup() {}
171 : :
172 : : //! Receive new mesh from Refiner (no-op)
173 : : void resizePostAMR(
174 : : const std::vector< std::size_t >&,
175 : : const tk::UnsMesh::Chunk&,
176 : : const tk::UnsMesh::Coords&,
177 : : const std::unordered_map< std::size_t, tk::UnsMesh::Edge >&,
178 : : const std::unordered_map< std::size_t, std::size_t >&,
179 : : const std::set< std::size_t >&,
180 : : const std::unordered_map< std::size_t, std::size_t >&,
181 : : const tk::NodeCommMap&,
182 : : const std::map< int, std::vector< std::size_t > >&,
183 : : const std::map< int, std::vector< std::size_t > >&,
184 : : const std::vector< std::size_t >&,
185 : : const std::unordered_map< std::size_t, std::set< std::size_t > >& ) {}
186 : :
187 : : //! Resizing data structures after mesh refinement has completed (no-op)
188 : : void resized() {}
189 : :
190 : : /** @name Charm++ pack/unpack serializer member functions */
191 : : ///@{
192 : : //! \brief Pack/Unpack serialize member function
193 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference
194 : 2949 : void pup( PUP::er &p ) override {
195 : 2949 : p | m_disc;
196 : 2949 : p | m_nsol;
197 : 2949 : p | m_ngrad;
198 : 2949 : p | m_nrhs;
199 : 2949 : p | m_nbnorm;
200 : 2949 : p | m_ndfnorm;
201 : 2949 : p | m_nmblk;
202 : 2949 : p | m_bnode;
203 : 2949 : p | m_bface;
204 : 2949 : p | m_triinpoel;
205 : 2949 : p | m_bndel;
206 : 2949 : p | m_dfnorm;
207 : 2949 : p | m_dfnormc;
208 : 2949 : p | m_dfn;
209 : 2949 : p | m_esup;
210 : 2949 : p | m_psup;
211 : 2949 : p | m_u;
212 : 2949 : p | m_uc;
213 : 2949 : p | m_un;
214 : 2949 : p | m_rhs;
215 : 2949 : p | m_rhsc;
216 : 2949 : p | m_chBndGrad;
217 : 2949 : p | m_dirbc;
218 : 2949 : p | m_chBndGradc;
219 : 2949 : p | m_blank;
220 : : p | m_diag;
221 : 2949 : p | m_bnorm;
222 : 2949 : p | m_bnormc;
223 : 2949 : p | m_symbcnodes;
224 : 2949 : p | m_farfieldbcnodes;
225 : 2949 : p | m_symbctri;
226 : 2949 : p | m_timedepbcnodes;
227 : 2949 : p | m_timedepbcFn;
228 : 2949 : p | m_stage;
229 : 2949 : p | m_boxnodes;
230 : 2949 : p | m_edgenode;
231 : 2949 : p | m_edgeid;
232 : 2949 : p | m_dtp;
233 : 2949 : p | m_tp;
234 : 2949 : p | m_finished;
235 : 2949 : p | m_movedmesh;
236 : 2949 : p | m_nusermeshblk;
237 : 2949 : p | m_nodeblockid;
238 : 2949 : p | m_nodeblockidc;
239 : 2949 : p | m_ixfer;
240 : : p | m_uservel;
241 : 2949 : }
242 : : //! \brief Pack/Unpack serialize operator|
243 : : //! \param[in,out] p Charm++'s PUP::er serializer object reference
244 : : //! \param[in,out] i OversetFE object reference
245 : : friend void operator|( PUP::er& p, OversetFE& i ) { i.pup(p); }
246 : : //@}
247 : :
248 : : private:
249 : : using ncomp_t = tk::ncomp_t;
250 : :
251 : : //! Discretization proxy
252 : : CProxy_Discretization m_disc;
253 : : //! Counter for high order solution vector nodes updated
254 : : std::size_t m_nsol;
255 : : //! Counter for nodal gradients updated
256 : : std::size_t m_ngrad;
257 : : //! Counter for right-hand side vector nodes updated
258 : : std::size_t m_nrhs;
259 : : //! Counter for receiving boundary point normals
260 : : std::size_t m_nbnorm;
261 : : //! Counter for receiving dual-face normals on chare-boundary edges
262 : : std::size_t m_ndfnorm;
263 : : //! Counter for mesh block nodes updated
264 : : std::size_t m_nmblk;
265 : : //! Boundary node lists mapped to side set ids used in the input file
266 : : std::map< int, std::vector< std::size_t > > m_bnode;
267 : : //! Boundary face lists mapped to side set ids used in the input file
268 : : std::map< int, std::vector< std::size_t > > m_bface;
269 : : //! Boundary triangle face connecitivity where BCs are set by user
270 : : std::vector< std::size_t > m_triinpoel;
271 : : //! Elements along mesh boundary
272 : : std::vector< std::size_t > m_bndel;
273 : : //! Dual-face normals along edges
274 : : std::unordered_map< tk::UnsMesh::Edge, std::array< tk::real, 3 >,
275 : : tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> > m_dfnorm;
276 : : //! Receive buffer for dual-face normals along chare-boundary edges
277 : : std::unordered_map< tk::UnsMesh::Edge, std::array< tk::real, 3 >,
278 : : tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> > m_dfnormc;
279 : : //! Streamable dual-face normals
280 : : std::vector< tk::real > m_dfn;
281 : : //! El;ements surrounding points
282 : : std::pair< std::vector< std::size_t >, std::vector< std::size_t > > m_esup;
283 : : //! Points surrounding points
284 : : std::pair< std::vector< std::size_t >, std::vector< std::size_t > > m_psup;
285 : : //! Unknown/solution vector at mesh nodes
286 : : tk::Fields m_u;
287 : : //! \brief Copy of unknown/solution vector at mesh nodes for m2m transfer,
288 : : //! appended with a solution-transfer-flag. This flag indicates
289 : : //! appropriate solution transfers for the overset procedure.
290 : : //! Value 0: Do not transfer solution, 1: transfer sol, 2: blank nodes
291 : : //! TODO: avoid creating this copy
292 : : tk::Fields m_uc;
293 : : //! Unknown/solution vector at mesh nodes at previous time
294 : : tk::Fields m_un;
295 : : //! Right-hand side vector (for the high order system)
296 : : tk::Fields m_rhs;
297 : : //! Receive buffer for communication of the right hand side
298 : : //! \details Key: global node id, value: rhs for all scalar components per
299 : : //! node.
300 : : std::unordered_map< std::size_t, std::vector< tk::real > > m_rhsc;
301 : : //! Nodal gradients at chare-boundary nodes
302 : : tk::Fields m_chBndGrad;
303 : : //! Boundary conditions evaluated and assigned to local mesh node IDs
304 : : //! \details Vector of pairs of bool and boundary condition value associated
305 : : //! to local mesh node IDs at which the user has set Dirichlet boundary
306 : : //! conditions for all PDEs integrated. The bool indicates whether the BC
307 : : //! is set at the node for that component the if true, the real value is
308 : : //! the increment (from t to dt) in the BC specified for a component.
309 : : std::unordered_map< std::size_t,
310 : : std::vector< std::pair< bool, tk::real > > > m_dirbc;
311 : : //! Receive buffer for communication of the nodal gradients
312 : : //! \details Key: chare id, value: gradients for all scalar components per
313 : : //! node
314 : : std::unordered_map< std::size_t, std::vector< tk::real > > m_chBndGradc;
315 : : //! Blanking coefficient for overset, indicating hole in the background mesh
316 : : std::vector< tk::real > m_blank;
317 : : //! Diagnostics object
318 : : NodeDiagnostics m_diag;
319 : : //! Face normals in boundary points associated to side sets
320 : : //! \details Key: local node id, value: unit normal and inverse distance
321 : : //! square between face centroids and points, outer key: side set id
322 : : std::unordered_map< int,
323 : : std::unordered_map< std::size_t, std::array< tk::real, 4 > > > m_bnorm;
324 : : //! \brief Receive buffer for communication of the boundary point normals
325 : : //! associated to side sets
326 : : //! \details Key: global node id, value: normals (first 3 components),
327 : : //! inverse distance squared (4th component), outer key, side set id
328 : : std::unordered_map< int,
329 : : std::unordered_map< std::size_t, std::array< tk::real, 4 > > > m_bnormc;
330 : : //! Unique set of nodes at which symmetry BCs are set
331 : : std::unordered_set< std::size_t > m_symbcnodes;
332 : : //! Unique set of nodes at which farfield BCs are set
333 : : std::unordered_set< std::size_t > m_farfieldbcnodes;
334 : : //! Vector with 1 at symmetry BC boundary triangles
335 : : std::vector< int > m_symbctri;
336 : : //! \brief Unique set of nodes at which time dependent BCs are set
337 : : // for each time dependent BC
338 : : std::vector< std::unordered_set< std::size_t > > m_timedepbcnodes;
339 : : //! \brief User defined discrete function of time used in the time dependent
340 : : // BCs associated with (index in vector) the number of distinct time
341 : : // dependent BCs specified. This index is the same as the index in
342 : : // m_timedepbcnodes.
343 : : std::vector< tk::Table<5> > m_timedepbcFn;
344 : : //! Runge-Kutta stage counter
345 : : std::size_t m_stage;
346 : : //! Mesh node ids at which user-defined box ICs are defined (multiple boxes)
347 : : std::vector< std::unordered_set< std::size_t > > m_boxnodes;
348 : : //! Local node IDs of edges
349 : : std::vector< std::size_t > m_edgenode;
350 : : //! Edge ids in the order of access
351 : : std::vector< std::size_t > m_edgeid;
352 : : //! Time step size for each mesh node
353 : : std::vector< tk::real > m_dtp;
354 : : //! Physical time for each mesh node
355 : : std::vector< tk::real > m_tp;
356 : : //! True in the last time step
357 : : int m_finished;
358 : : //! True if overset mesh moved
359 : : int m_movedmesh;
360 : : //! Number of mesh-blocks with user-defined ICs
361 : : std::size_t m_nusermeshblk;
362 : : //! Local node ids associated with mesh block ids
363 : : std::unordered_map< std::size_t, std::set< std::size_t > > m_nodeblockid;
364 : : //! Receive buffer for communication of the mesh block ids
365 : : //! \details Key: mesh block id, value: set of global node ids for nodes
366 : : //! in this mesh block.
367 : : std::unordered_map< std::size_t, std::set< std::size_t > > m_nodeblockidc;
368 : : //! Counter for two-way transfer
369 : : std::size_t m_ixfer;
370 : : //! User-specified mesh velocity
371 : : std::array< tk::real, 3 > m_uservel;
372 : :
373 : : //! Access bound Discretization class pointer
374 : 2280432 : Discretization* Disc() const {
375 : : Assert( m_disc[ thisIndex ].ckLocal() != nullptr, "ckLocal() null" );
376 : 4560864 : return m_disc[ thisIndex ].ckLocal();
377 : : }
378 : :
379 : : //! Compute normal of dual-mesh associated to edge
380 : : std::array< tk::real, 3 >
381 : : edfnorm( const tk::UnsMesh::Edge& edge,
382 : : const std::unordered_map< tk::UnsMesh::Edge,
383 : : std::vector< std::size_t >,
384 : : tk::UnsMesh::Hash<2>, tk::UnsMesh::Eq<2> >& esued ) const;
385 : :
386 : : //! Compute chare-boundary edges
387 : : void bndEdges();
388 : :
389 : : //! Start (re-)computing boundare point-, and dual-face normals
390 : : void norm();
391 : :
392 : : //! Compute dual-face normals associated to edges
393 : : void dfnorm();
394 : :
395 : : //! Compute boundary point normals
396 : : void
397 : : bnorm( const std::unordered_map< int,
398 : : std::unordered_set< std::size_t > >& bcnodes );
399 : :
400 : : //! Set flags informing solution transfer decisions
401 : : void setTransferFlags(
402 : : std::size_t dirn );
403 : :
404 : : //! \brief Finish computing dual-face and boundary point normals and apply
405 : : //! boundary conditions on the initial conditions
406 : : void normfinal();
407 : :
408 : : //! Continue setup for solution, after communication for mesh blocks
409 : : void continueSetup();
410 : :
411 : : //! Output mesh field data and continue to next time step
412 : : void out();
413 : :
414 : : //! Output mesh-based fields to file
415 : : void writeFields( CkCallback c );
416 : :
417 : : //! Combine own and communicated contributions to normals
418 : : void mergelhs();
419 : :
420 : : //! Compute gradients
421 : : void chBndGrad();
422 : :
423 : : //! Compute righ-hand side vector of transport equations
424 : : void rhs();
425 : :
426 : : //! Advance systems of equations
427 : : void solve();
428 : :
429 : : //! Compute time step size
430 : : void dt();
431 : :
432 : : //! Evaluate whether to save checkpoint/restart
433 : : void evalRestart();
434 : :
435 : : //! Query/update boundary-conditions-related data structures from user input
436 : : void getBCNodes();
437 : :
438 : : // \brief Apply the transferred solution to the solution vector based on
439 : : // transfer flags previously set up
440 : : void applySolTransfer( std::size_t dirn );
441 : :
442 : : //! Apply boundary conditions
443 : : void BC();
444 : : };
445 : :
446 : : } // inciter::
447 : :
448 : : #endif // OversetFE_h
|