Cardinal
Loading...
Searching...
No Matches
NekRSProblem.h
Go to the documentation of this file.
1/********************************************************************/
2/* SOFTWARE COPYRIGHT NOTIFICATION */
3/* Cardinal */
4/* */
5/* (c) 2021 UChicago Argonne, LLC */
6/* ALL RIGHTS RESERVED */
7/* */
8/* Prepared by UChicago Argonne, LLC */
9/* Under Contract No. DE-AC02-06CH11357 */
10/* With the U. S. Department of Energy */
11/* */
12/* Prepared by Battelle Energy Alliance, LLC */
13/* Under Contract No. DE-AC07-05ID14517 */
14/* With the U. S. Department of Energy */
15/* */
16/* See LICENSE for full restrictions */
17/********************************************************************/
18
19#pragma once
20
21#include "CardinalProblem.h"
22#include "NekInterface.h"
23#include "NekTimeStepper.h"
24#include "NekScalarValue.h"
25#include "NekRSMesh.h"
26#include "Transient.h"
27
29
37{
38public:
39 NekRSProblem(const InputParameters & params);
40
41 static InputParameters validParams();
42
44
50 int nPoints() const { return _n_points; }
51
57 bool isDataTransferHappening(ExternalProblem::Direction direction);
58
59 Transient * transientExecutioner() const { return _transient_executioner; }
60
66 bool isUsrWrkSlotReservedForCoupling(const unsigned int & slot) const;
67
72 void copyIndividualScratchSlot(const unsigned int & slot) const;
73
80 void writeFieldFile(const Real & time, const int & step) const;
81
89 virtual bool isOutputStep() const;
90
91 virtual void initialSetup() override;
92
93 virtual void externalSolve() override;
94
95 virtual bool converged(unsigned int) override { return true; }
96
97 virtual void addExternalVariables() override;
98
99 virtual void syncSolutions(ExternalProblem::Direction direction) override;
100
105 virtual bool nondimensional() const { return _nondimensional; }
106
111 virtual const bool hasMovingNekMesh() const { return false; }
112
117 virtual bool synchronizeIn();
118
123 virtual bool synchronizeOut();
124
129 unsigned int nUsrWrkSlots() const { return _n_usrwrk_slots; }
130
136 template <typename T>
137 void volumeSolution(const T & field, double * s)
138 {
139 mesh_t * mesh = nekrs::entireMesh();
140 auto vc = _nek_mesh->volumeCoupling();
141
142 double (*f)(int, int);
144
145 int start_1d = mesh->Nq;
146 int end_1d = _moose_Nq;
147 int start_3d = start_1d * start_1d * start_1d;
148 int end_3d = end_1d * end_1d * end_1d;
149 int n_to_write = vc.n_elems * end_3d * _nek_mesh->nBuildPerVolumeElem();
150
151 // allocate temporary space:
152 // - Ttmp: results of the search for each process
153 // - Telem: scratch space for volume interpolation to avoid reallocating a bunch (only used if
154 // interpolating)
155 double * Ttmp = (double *)calloc(n_to_write, sizeof(double));
156 double * Telem = (double *)calloc(start_3d, sizeof(double));
157 auto indices = _nek_mesh->cornerIndices();
158
159 int c = 0;
160 for (int k = 0; k < mesh->Nelements; ++k)
161 {
162 int offset = k * start_3d;
163
164 for (int build = 0; build < _nek_mesh->nBuildPerVolumeElem(); ++build)
165 {
167 {
168 // get the solution on the element
169 for (int v = 0; v < start_3d; ++v)
170 Telem[v] = f(offset + v, 0 /* unused for volumes */);
171
172 // and then interpolate it
174 _interpolation_outgoing, Telem, start_1d, &(Ttmp[c]), end_1d);
175 c += end_3d;
176 }
177 else
178 {
179 // get the solution on the element - no need to interpolate
180 for (int v = 0; v < end_3d; ++v, ++c)
181 Ttmp[c] = f(offset + indices[build][v], 0 /* unused for volumes */);
182 }
183 }
184 }
185
186 // dimensionalize the solution if needed
187 for (int v = 0; v < n_to_write; ++v)
188 Ttmp[v] =
190
191 nekrs::allgatherv(vc.mirror_counts, Ttmp, s, end_3d);
192
193 freePointer(Ttmp);
194 freePointer(Telem);
195 }
196
202 template <typename T>
203 void boundarySolution(const T & field, double * s)
204 {
205 mesh_t * mesh = nekrs::entireMesh();
206 auto bc = _nek_mesh->boundaryCoupling();
207
208 double (*f)(int, int);
210
211 int start_1d = mesh->Nq;
212 int end_1d = _moose_Nq;
213 int start_2d = start_1d * start_1d;
214 int end_2d = end_1d * end_1d;
215
216 int n_to_write = bc.n_faces * end_2d * _nek_mesh->nBuildPerSurfaceElem();
217
218 // allocate temporary space:
219 // - Ttmp: results of the search for each process
220 // - Tface: scratch space for face solution to avoid reallocating a bunch (only used if
221 // interpolating)
222 // - scratch: scratch for the interpolatino process to avoid reallocating a bunch (only used if
223 // interpolating0
224 double * Ttmp = (double *)calloc(n_to_write, sizeof(double));
225 double * Tface = (double *)calloc(start_2d, sizeof(double));
226 double * scratch = (double *)calloc(start_1d * end_1d, sizeof(double));
227
228 auto indices = _nek_mesh->cornerIndices();
229
230 int c = 0;
231 for (int k = 0; k < bc.total_n_faces; ++k)
232 {
233 if (bc.process[k] == nekrs::commRank())
234 {
235 int i = bc.element[k];
236 int j = bc.face[k];
237 int offset = i * mesh->Nfaces * start_2d + j * start_2d;
238
239 for (int build = 0; build < _nek_mesh->nBuildPerSurfaceElem(); ++build)
240 {
242 {
243 // get the solution on the face
244 for (int v = 0; v < start_2d; ++v)
245 {
246 int id = mesh->vmapM[offset + v];
247 Tface[v] = f(id, mesh->Nsgeo * (offset + v));
248 }
249
250 // and then interpolate it
252 scratch, _interpolation_outgoing, Tface, start_1d, &(Ttmp[c]), end_1d);
253 c += end_2d;
254 }
255 else
256 {
257 // get the solution on the face - no need to interpolate
258 for (int v = 0; v < end_2d; ++v, ++c)
259 {
260 int id = mesh->vmapM[offset + indices[build][v]];
261 Ttmp[c] = f(id, mesh->Nsgeo * (offset + v));
262 }
263 }
264 }
265 }
266 }
267
268 // dimensionalize the solution if needed
269 for (int v = 0; v < n_to_write; ++v)
270 Ttmp[v] =
272
273 nekrs::allgatherv(bc.mirror_counts, Ttmp, s, end_2d);
274
275 freePointer(Ttmp);
276 freePointer(Tface);
277 freePointer(scratch);
278 }
279
287 void writeVolumeDisplacement(const int elem_id,
288 double * s,
289 const field::NekWriteEnum f,
290 const std::vector<double> * add = nullptr);
301 void writeVolumeSolution(const int slot,
302 const int elem_id,
303 double * s,
304 const std::vector<double> * add = nullptr);
305
313 void writeBoundarySolution(const int slot, const int elem_id, double * s);
314
319 std::string casename() const { return _casename; }
320
331 void mapFaceDataToNekFace(const unsigned int & e,
332 const unsigned int & var_num,
333 const Real & divisor,
334 const Real & additive,
335 double ** outgoing_data);
336
347 void mapVolumeDataToNekVolume(const unsigned int & e,
348 const unsigned int & var_num,
349 const Real & divisor,
350 const Real & additive,
351 double ** outgoing_data);
352
372 void mapFaceDataToNekVolume(const unsigned int & e,
373 const unsigned int & var_num,
374 const Real & divisor,
375 const Real & additive,
376 double ** outgoing_data);
377
378protected:
381
387 void interpolateBoundarySolutionToNek(double * incoming_moose_value, double * outgoing_nek_value);
388
395 void interpolateVolumeSolutionToNek(const int elem_id,
396 double * incoming_moose_value,
397 double * outgoing_nek_value);
398
401
402 std::unique_ptr<NumericVector<Number>> _serialized_solution;
403
409 std::string fieldFilePrefix(const int & number) const;
410
412 const std::string & _casename;
413
428 const bool & _write_fld_files;
429
432
435
444 unsigned int _n_usrwrk_slots;
445
447 const unsigned int & _constant_interval;
448
451
454
457
460
463
466
469
475
478
480 Transient * _transient_executioner = nullptr;
481
487
490
492 const PostprocessorValue * _transfer_in = nullptr;
493
495 double * _interpolation_outgoing = nullptr;
496
498 double * _interpolation_incoming = nullptr;
499
502
504 const std::vector<unsigned int> * _usrwrk_output = nullptr;
505
507 const std::vector<std::string> * _usrwrk_output_prefix = nullptr;
508
511
514
517
520
561
563 static bool _first;
564
566 std::vector<FieldTransferBase *> _field_transfers;
567
569 std::vector<ScalarTransferBase *> _scalar_transfers;
570
572 std::set<unsigned int> _usrwrk_slots;
573};
@ mesh
Definition CardinalEnums.h:288
void freePointer(T *ptr)
Definition CardinalUtils.h:23
Definition CardinalProblem.h:27
Definition FieldTransferBase.h:29
Definition NekRSMesh.h:51
int nBuildPerVolumeElem() const
Definition NekRSMesh.h:77
int nBuildPerSurfaceElem() const
Definition NekRSMesh.h:83
std::vector< std::vector< int > > cornerIndices() const
Definition NekRSMesh.h:308
const NekVolumeCoupling & volumeCoupling() const
Definition NekRSMesh.h:131
const NekBoundaryCoupling & boundaryCoupling() const
Definition NekRSMesh.h:125
Solve nekRS wrapped as a MOOSE app.
Definition NekRSProblem.h:37
void interpolateBoundarySolutionToNek(double *incoming_moose_value, double *outgoing_nek_value)
double _tSolveStepMin
Minimum step solve time.
Definition NekRSProblem.h:516
void mapVolumeDataToNekVolume(const unsigned int &e, const unsigned int &var_num, const Real &divisor, const Real &additive, double **outgoing_data)
const bool & _disable_fld_file_output
Whether to turn off all field file writing.
Definition NekRSProblem.h:431
bool _is_output_step
Whether the most recent time step was an output file writing step.
Definition NekRSProblem.h:468
static InputParameters validParams()
const std::vector< unsigned int > * _usrwrk_output
Slots in the nrs->o_usrwrk array to write to a field file.
Definition NekRSProblem.h:504
void copyIndividualScratchSlot(const unsigned int &slot) const
bool isUsrWrkSlotReservedForCoupling(const unsigned int &slot) const
Transient * _transient_executioner
Underlying executioner.
Definition NekRSProblem.h:480
virtual const bool hasMovingNekMesh() const
Definition NekRSProblem.h:111
virtual bool isOutputStep() const
Whether nekRS should write an output file for the current time step.
void writeVolumeSolution(const int slot, const int elem_id, double *s, const std::vector< double > *add=nullptr)
int _n_points
Number of points for interpolated fields on the MOOSE mesh.
Definition NekRSProblem.h:489
const std::vector< std::string > * _usrwrk_output_prefix
Filename prefix to use for naming the field files containing the nrs->o_usrwrk array slots.
Definition NekRSProblem.h:507
NekRSMesh * _nek_mesh
Definition NekRSProblem.h:474
void writeVolumeDisplacement(const int elem_id, double *s, const field::NekWriteEnum f, const std::vector< double > *add=nullptr)
virtual bool synchronizeOut()
void interpolateVolumeSolutionToNek(const int elem_id, double *incoming_moose_value, double *outgoing_nek_value)
static bool _first
flag to indicate whether this is the first pass to serialize the solution
Definition NekRSProblem.h:563
virtual void addExternalVariables() override
virtual void initialSetup() override
void boundarySolution(const T &field, double *s)
Definition NekRSProblem.h:203
NekTimeStepper * _timestepper
The time stepper used for selection of time step size.
Definition NekRSProblem.h:477
std::vector< FieldTransferBase * > _field_transfers
All of the FieldTransfer objects which pass data in/out of NekRS.
Definition NekRSProblem.h:566
unsigned int _n_usrwrk_slots
Definition NekRSProblem.h:444
int _n_vertices_per_volume
Number of vertices per volume element of the transfer mesh.
Definition NekRSProblem.h:462
double _elapsedTime
Sum of the total elapsed time in NekRS solves.
Definition NekRSProblem.h:513
const bool & _skip_final_field_file
Whether to skip writing a field file on NekRS's last time steo.
Definition NekRSProblem.h:450
int _n_vertices_per_surface
Number of vertices per surface element of the transfer mesh.
Definition NekRSProblem.h:456
void copyHostToDevice()
Copy the data sent from MOOSE->Nek from host to device.
virtual void syncSolutions(ExternalProblem::Direction direction) override
void mapFaceDataToNekFace(const unsigned int &e, const unsigned int &var_num, const Real &divisor, const Real &additive, double **outgoing_data)
std::string casename() const
Definition NekRSProblem.h:319
double _start_time
Start time of the simulation based on NekRS's .par file.
Definition NekRSProblem.h:465
const std::string & _casename
NekRS casename.
Definition NekRSProblem.h:412
bool isDataTransferHappening(ExternalProblem::Direction direction)
void volumeSolution(const T &field, double *s)
Definition NekRSProblem.h:137
double * _interpolation_incoming
Vandermonde interpolation matrix (for incoming transfers)
Definition NekRSProblem.h:498
virtual bool synchronizeIn()
double * _interpolation_outgoing
Vandermonde interpolation matrix (for outgoing transfers)
Definition NekRSProblem.h:495
void writeBoundarySolution(const int slot, const int elem_id, double *s)
bool _needs_interpolation
Definition NekRSProblem.h:486
void initializeInterpolationMatrices()
Initialize interpolation matrices for transfers in/out of nekRS.
std::vector< ScalarTransferBase * > _scalar_transfers
All of the ScalarTransfer objecst which pass data in/out of NekRS.
Definition NekRSProblem.h:569
std::set< unsigned int > _usrwrk_slots
Usrwrk slots managed by Cardinal.
Definition NekRSProblem.h:572
virtual bool converged(unsigned int) override
Definition NekRSProblem.h:95
virtual void externalSolve() override
synchronization::SynchronizationEnum _sync_interval
When to synchronize the NekRS solution with the mesh mirror.
Definition NekRSProblem.h:560
Transient * transientExecutioner() const
Definition NekRSProblem.h:59
unsigned int nUsrWrkSlots() const
Definition NekRSProblem.h:129
const PostprocessorValue * _transfer_in
Postprocessor containing the signal of when a synchronization has occurred.
Definition NekRSProblem.h:492
int nPoints() const
Definition NekRSProblem.h:50
const unsigned int & _constant_interval
For constant synchronization intervals, the desired frequency (in units of Nek time steps)
Definition NekRSProblem.h:447
void mapFaceDataToNekVolume(const unsigned int &e, const unsigned int &var_num, const Real &divisor, const Real &additive, double **outgoing_data)
Map nodal points on a MOOSE face element to the GLL points on a Nek volume element.
virtual bool nondimensional() const
Definition NekRSProblem.h:105
int _n_surface_elems
Number of surface elements in the data transfer mesh, across all processes.
Definition NekRSProblem.h:453
bool _nondimensional
Whether a dimensionalization action has been added.
Definition NekRSProblem.h:434
double _tSolveStepMax
Maximum step solve time.
Definition NekRSProblem.h:519
int _n_volume_elems
Number of volume elements in the data transfer mesh, across all processes.
Definition NekRSProblem.h:459
int _moose_Nq
For the MOOSE mesh, the number of quadrature points in each coordinate direction.
Definition NekRSProblem.h:501
std::string fieldFilePrefix(const int &number) const
NekRSProblem(const InputParameters &params)
void writeFieldFile(const Real &time, const int &step) const
double _elapsedStepSum
Sum of the elapsed time in NekRS solves.
Definition NekRSProblem.h:510
const bool & _write_fld_files
Definition NekRSProblem.h:428
std::unique_ptr< NumericVector< Number > > _serialized_solution
Definition NekRSProblem.h:402
Time stepper that reads time step information directly from nekRS.
Definition NekTimeStepper.h:38
Definition CardinalEnums.h:93
NekWriteEnum
Enumeration of possible fields to write in nekRS.
Definition CardinalEnums.h:119
void interpolateVolumeHex3D(const double *I, double *x, int N, double *Ix, int M)
void allgatherv(const std::vector< int > &base_counts, const T *input, T *output, const int multiplier=1)
Definition NekInterface.h:1017
Real nondimensionalAdditive(const field::NekFieldEnum &field)
void interpolateSurfaceFaceHex3D(double *scratch, const double *I, double *x, int N, double *Ix, int M)
int commRank()
double(*)(int, int) solutionPointer(const field::NekFieldEnum &field)
Definition NekInterface.h:794
mesh_t * entireMesh()
Real nondimensionalDivisor(const field::NekFieldEnum &field)
Return the reference divisor scale that defines the non-dimensional field.
SynchronizationEnum
Definition CardinalEnums.h:66