New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Vpp visualization #11274
Vpp visualization #11274
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# VectorPostprocessorVisualizationAux | ||
|
||
## Short Description | ||
|
||
!syntax description /AuxKernels/VectorPostprocessorVisualizationAux | ||
|
||
## Description | ||
|
||
This object is intended to let you view VectorPostprocessor vectors that are of lenght `num_procs` (meaning there is one value per MPI process). This object will take those values and fill up an Auxiliary field with them so the values can be visualized. | ||
|
||
## Important Notes | ||
|
||
Note: the VectorPostprocessor must be syncing the vectors it's computing to all processors. By default many just compute to processor 0 (because that's where output occurrs). | ||
|
||
For instance: this is the case for [WorkBalance](WorkBalance.md). By default it only syncs to processor 0, but it has a parameter (`sync_to_all_procs`) to tell it to create copies of the vectors on all processors. | ||
|
||
!syntax parameters /AuxKernels/VectorPostprocessorVisualizationAux | ||
|
||
!syntax inputs /AuxKernels/VectorPostprocessorVisualizationAux | ||
|
||
!syntax children /AuxKernels/VectorPostprocessorVisualizationAux | ||
|
||
!bibtex bibliography |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
//* This file is part of the MOOSE framework | ||
//* https://www.mooseframework.org | ||
//* | ||
//* All rights reserved, see COPYRIGHT for full restrictions | ||
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT | ||
//* | ||
//* Licensed under LGPL 2.1, please see LICENSE for details | ||
//* https://www.gnu.org/licenses/lgpl-2.1.html | ||
|
||
#ifndef VECTORPOSTPROCESSORVISUALIZATIONAUX_H | ||
#define VECTORPOSTPROCESSORVISUALIZATIONAUX_H | ||
|
||
#include "AuxKernel.h" | ||
|
||
// Forward Declarations | ||
class VectorPostprocessorVisualizationAux; | ||
|
||
template <> | ||
InputParameters validParams<VectorPostprocessorVisualizationAux>(); | ||
|
||
/** | ||
* Read values from a VectorPostprocessor that is producing vectors that are "number of processors" | ||
* in length. Puts the value for each processor into an elemental auxiliary field. | ||
*/ | ||
class VectorPostprocessorVisualizationAux : public AuxKernel | ||
{ | ||
public: | ||
VectorPostprocessorVisualizationAux(const InputParameters & parameters); | ||
|
||
protected: | ||
/** | ||
* Note: this used for error checking. It's done very late because VPP's don't fill in their | ||
* vectors until they are computed | ||
*/ | ||
virtual void timestepSetup() override; | ||
|
||
/** | ||
* Get the value from the vector and assign it to the element | ||
*/ | ||
virtual Real computeValue() override; | ||
|
||
/// Holds the values we want to display | ||
const VectorPostprocessorValue & _vpp_vector; | ||
|
||
/// Optimization | ||
processor_id_type _my_pid; | ||
}; | ||
|
||
#endif // VECTORPOSTPROCESSORVISUALIZATIONAUX_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
//* This file is part of the MOOSE framework | ||
//* https://www.mooseframework.org | ||
//* | ||
//* All rights reserved, see COPYRIGHT for full restrictions | ||
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT | ||
//* | ||
//* Licensed under LGPL 2.1, please see LICENSE for details | ||
//* https://www.gnu.org/licenses/lgpl-2.1.html | ||
|
||
#include "VectorPostprocessorVisualizationAux.h" | ||
|
||
registerMooseObject("MooseApp", VectorPostprocessorVisualizationAux); | ||
|
||
template <> | ||
InputParameters | ||
validParams<VectorPostprocessorVisualizationAux>() | ||
{ | ||
InputParameters params = validParams<AuxKernel>(); | ||
|
||
params.addClassDescription("Read values from a VectorPostprocessor that is producing vectors " | ||
"that are 'number of processors' * in length. Puts the value for " | ||
"each processor into an elemental auxiliary field."); | ||
|
||
params.addRequiredParam<VectorPostprocessorName>( | ||
"vpp", "The name of the VectorPostprocessor to pull the data from."); | ||
params.addRequiredParam<std::string>( | ||
"vector_name", "The name of the vector to use from the VectorPostprocessor"); | ||
|
||
return params; | ||
} | ||
|
||
VectorPostprocessorVisualizationAux::VectorPostprocessorVisualizationAux( | ||
const InputParameters & parameters) | ||
: AuxKernel(parameters), | ||
_vpp_vector(getVectorPostprocessorValue("vpp", getParam<std::string>("vector_name"))), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interesting that this works here. It actually isn't correct. We have all of those "ByName" variants, which take the parameter name (instead of the actual name). This might mean we have another bug in the retrieval of VPPs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's right the way it is - it is using the non "by name" version on purpose. There is no such thing for the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
_my_pid(processor_id()) | ||
{ | ||
} | ||
|
||
void | ||
VectorPostprocessorVisualizationAux::timestepSetup() | ||
{ | ||
if (_vpp_vector.size() != n_processors()) | ||
mooseError("Error in VectorPostprocessor ", | ||
name(), | ||
". Vector ", | ||
getParam<std::string>("vector_name"), | ||
" in VectorPostprocessor ", | ||
getParam<VectorPostprocessorName>("vpp"), | ||
" does not contain num_procs number of entries. num_procs: ", | ||
n_processors(), | ||
" num_entries: ", | ||
_vpp_vector.size()); | ||
} | ||
|
||
Real | ||
VectorPostprocessorVisualizationAux::computeValue() | ||
{ | ||
return _vpp_vector[_my_pid]; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,12 +34,20 @@ validParams<WorkBalance>() | |
system_enum, | ||
"The system(s) to retrieve the number of DOFs from (NL, AUX, ALL). Default == ALL"); | ||
|
||
params.addParam<bool>("sync_to_all_procs", | ||
false, | ||
"Whether or not to sync the vectors to all processors. By default we only " | ||
"sync them to processor 0 so they can be written out. Setting this to " | ||
"true will use more communication, but is necessary if you expect these " | ||
"vectors to be available on all processors"); | ||
|
||
return params; | ||
} | ||
|
||
WorkBalance::WorkBalance(const InputParameters & parameters) | ||
: GeneralVectorPostprocessor(parameters), | ||
_system(getParam<MooseEnum>("system")), | ||
_sync_to_all_procs(getParam<bool>("sync_to_all_procs")), | ||
_local_num_elems(0), | ||
_local_num_nodes(0), | ||
_local_num_dofs(0), | ||
|
@@ -245,12 +253,24 @@ WorkBalance::execute() | |
void | ||
WorkBalance::finalize() | ||
{ | ||
// Gather the results down to processor 0 | ||
_communicator.gather(0, static_cast<Real>(_local_num_elems), _num_elems); | ||
_communicator.gather(0, static_cast<Real>(_local_num_nodes), _num_nodes); | ||
_communicator.gather(0, static_cast<Real>(_local_num_dofs), _num_dofs); | ||
_communicator.gather(0, static_cast<Real>(_local_num_partition_sides), _num_partition_sides); | ||
_communicator.gather(0, _local_partition_surface_area, _partition_surface_area); | ||
if (!_sync_to_all_procs) | ||
{ | ||
// Gather the results down to processor 0 | ||
_communicator.gather(0, static_cast<Real>(_local_num_elems), _num_elems); | ||
_communicator.gather(0, static_cast<Real>(_local_num_nodes), _num_nodes); | ||
_communicator.gather(0, static_cast<Real>(_local_num_dofs), _num_dofs); | ||
_communicator.gather(0, static_cast<Real>(_local_num_partition_sides), _num_partition_sides); | ||
_communicator.gather(0, _local_partition_surface_area, _partition_surface_area); | ||
} | ||
else | ||
{ | ||
// Gather the results down to all procs | ||
_communicator.allgather(static_cast<Real>(_local_num_elems), _num_elems); | ||
_communicator.allgather(static_cast<Real>(_local_num_nodes), _num_nodes); | ||
_communicator.allgather(static_cast<Real>(_local_num_dofs), _num_dofs); | ||
_communicator.allgather(static_cast<Real>(_local_num_partition_sides), _num_partition_sides); | ||
_communicator.allgather(_local_partition_surface_area, _partition_surface_area); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This really isn't the right idea here. You should be using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nope. All processors are contributing one value that gets inserted in their Read up: http://mpitutorial.com/tutorials/mpi-scatter-gather-and-allgather/ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to record our conversation that we had offline here: What I was after here was There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BTW - I thought of something else that could help out here. We have the I think we should consider fleshing this interface out more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 resolved |
||
} | ||
|
||
// Fill in the PID column - this just makes plotting easier | ||
_pid.resize(_num_elems.size()); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[Tests] | ||
[./test] | ||
type = 'Exodiff' | ||
input = 'vector_postprocessor_visualization.i' | ||
exodiff = 'vector_postprocessor_visualization_out.e' | ||
min_parallel = 3 | ||
max_parallel = 3 | ||
mesh_mode = replicated # Just because of the gold file | ||
[../] | ||
[] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
[Mesh] | ||
type = GeneratedMesh | ||
dim = 2 | ||
nx = 10 | ||
ny = 10 | ||
parallel_type = REPLICATED | ||
partitioner = linear | ||
[] | ||
|
||
[Variables] | ||
[u] | ||
[] | ||
[] | ||
|
||
[Kernels] | ||
[diff] | ||
type = Diffusion | ||
variable = u | ||
[] | ||
[] | ||
|
||
[BCs] | ||
[left] | ||
type = DirichletBC | ||
variable = u | ||
boundary = 'left' | ||
value = 0 | ||
[] | ||
[right] | ||
type = DirichletBC | ||
variable = u | ||
boundary = 'right' | ||
value = 1 | ||
[] | ||
[] | ||
|
||
[Executioner] | ||
type = Steady | ||
solve_type = PJFNK | ||
petsc_options_iname = '-pc_type -pc_hypre_type' | ||
petsc_options_value = 'hypre boomeramg' | ||
[] | ||
|
||
[Outputs] | ||
exodus = true | ||
[] | ||
|
||
[AuxVariables] | ||
[num_elems] | ||
family = MONOMIAL | ||
order = CONSTANT | ||
[] | ||
[partition_surface_area] | ||
family = MONOMIAL | ||
order = CONSTANT | ||
[] | ||
[] | ||
|
||
[AuxKernels] | ||
[wb_num_elems] | ||
type = VectorPostprocessorVisualizationAux | ||
vpp = 'wb' | ||
vector_name = num_elems | ||
variable = num_elems | ||
execute_on = 'TIMESTEP_END' | ||
[] | ||
[wb_partition_surface_area] | ||
type = VectorPostprocessorVisualizationAux | ||
vpp = 'wb' | ||
vector_name = partition_surface_area | ||
variable = partition_surface_area | ||
execute_on = 'TIMESTEP_END' | ||
[] | ||
[] | ||
|
||
[VectorPostprocessors] | ||
[wb] | ||
type = WorkBalance | ||
sync_to_all_procs = 'true' | ||
execute_on = 'INITIAL' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this be 'TIMESTEP_END' too if you are visualizing every timestep (see above)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nope - the issue is a dependency resolution issue. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh! Then this is a bug! VectorPostprocessors should be using the same PRE/POST logic as PostProcessors (and UserObjects). I'll checkout your branch and see if I can fix this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK - So there isn't a bug here. Turns out that the check in |
||
[] | ||
[] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess as a utility this is fine, but there are better ways to accomplish this. If you take a step back and look at these new utilities you've added in the past week, you are essentially taking local only information, replicating it on all processors, then using the local only information. We could have just never sent it in the first place if you are only using the AuxKernel, but I suppose you may want both the VPP information and the visualization field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok - can you enumerate the "better ways"? And I'd like to see some citations on
these new utilities you've added in the past week, you are essentially taking local only information, replicating it on all processors, then using the local only information
Where?
First of all - I didn't
replicate information to all
at all with any of my previous utilities. WorkBalance, HistogramVectorPostprocessor and StatisticsVectorPostprocessor only compute final values on processor zero (by default).Besides that - HistorgramVectorPostprocessor and StatisticsVectorPostprocessor work on any VPP... not just VPPs that compute one value per processor. For instance: you can use it to compute the mean, max, sum, average or get the Histogram of values found by a LineValueSampler... including the statistics/historgram for all of the variables you sampled by that LineValueSampler. Please let me know how else you would do this.
I will agree that in this case for visualization- for WorkBalance - it needs to broadcast to get a copy of the information on each processor - but there might be other reasons for doing that besides just visualizing it. AND this utility is not only intended for WorkBalance alone... I'm going to use it to do many other things with... where I already have the vectors on each processor (like my ray tracing data).
What I'm making here are basic tools. I have many other plans for them going forward with my dissertation. If you don't find them useful then I'll just put them in my app. I know that many of these will get used a TON by many people over the years.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also: please tell me how to get the partition surface area on each processor and paint it into a field only using an AuxKernel?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 resolved