Skip to content

Commit

Permalink
refactoring problem creation to allow custom actions to create specia…
Browse files Browse the repository at this point in the history
…l problems #12002
  • Loading branch information
YaqiWang committed Aug 30, 2018
1 parent ccf2235 commit b61de47
Show file tree
Hide file tree
Showing 14 changed files with 229 additions and 148 deletions.
12 changes: 0 additions & 12 deletions framework/include/actions/CreateProblemAction.h
Expand Up @@ -12,7 +12,6 @@

// MOOSE includes
#include "MooseObjectAction.h"
#include "MultiMooseEnum.h"

class CreateProblemAction;

Expand All @@ -25,17 +24,6 @@ class CreateProblemAction : public MooseObjectAction
CreateProblemAction(InputParameters parameters);

virtual void act() override;

void CreateTagVectors();

protected:
std::vector<SubdomainName> _blocks;
MultiMooseEnum _coord_sys;
/// One entry of coord system per block, the size of _blocks and _coord_sys has to match, except:
/// 1. _blocks.size() == 0, then there needs to be just one entry in _coord_sys, which will
/// be set for the whole domain
/// 2. _blocks.size() > 0 and no coordinate system was specified, then the whole domain will be XYZ.
/// 3. _blocks.size() > 0 and one coordinate system was specified, then the whole domain will be that system.
};

#endif /* CREATEPROBLEMACTION_H */
29 changes: 29 additions & 0 deletions framework/include/actions/CreateProblemDefaultAction.h
@@ -0,0 +1,29 @@
//* 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 CREATEPROBLEMDEFAULTACTION_H
#define CREATEPROBLEMDEFAULTACTION_H

// MOOSE includes
#include "Action.h"

class CreateProblemDefaultAction;

template <>
InputParameters validParams<CreateProblemDefaultAction>();

class CreateProblemDefaultAction : public Action
{
public:
CreateProblemDefaultAction(InputParameters parameters);

virtual void act() override;
};

#endif /* CREATEPROBLEMDEFAULTACTION_H */
2 changes: 2 additions & 0 deletions framework/include/problems/FEProblemBase.h
Expand Up @@ -1486,6 +1486,8 @@ class FEProblemBase : public SubProblem, public Restartable
bool constJacobian() const;

protected:
void CreateTagVectors();

MooseMesh & _mesh;
EquationSystems _eq;
bool _initialized;
Expand Down
124 changes: 16 additions & 108 deletions framework/src/actions/CreateProblemAction.C
Expand Up @@ -20,51 +20,13 @@ template <>
InputParameters
validParams<CreateProblemAction>()
{
MultiMooseEnum coord_types("XYZ RZ RSPHERICAL", "XYZ");
MooseEnum rz_coord_axis("X=0 Y=1", "Y");

InputParameters params = validParams<MooseObjectAction>();
params.set<std::string>("type") = "FEProblem";
params.addParam<std::string>("type", "FEProblem", "Problem type");
params.addParam<std::string>("name", "MOOSE Problem", "The name the problem");
params.addParam<std::vector<SubdomainName>>("block", "Block IDs for the coordinate systems");
params.addParam<MultiMooseEnum>(
"coord_type", coord_types, "Type of the coordinate system per block param");
params.addParam<MooseEnum>(
"rz_coord_axis", rz_coord_axis, "The rotation axis (X | Y) for axisymetric coordinates");
params.addParam<bool>(
"kernel_coverage_check", true, "Set to false to disable kernel->subdomain coverage check");
params.addParam<bool>("material_coverage_check",
true,
"Set to false to disable material->subdomain coverage check");
params.addParam<bool>("parallel_barrier_messaging",
true,
"Displays messaging from parallel "
"barrier notifications when executing "
"or transferring to/from Multiapps "
"(default: true)");

params.addParam<FileNameNoExtension>("restart_file_base",
"File base name used for restart (e.g. "
"<path>/<filebase> or <path>/LATEST to "
"grab the latest file available)");

params.addParam<std::vector<TagName>>("extra_tag_vectors",
"Extra vectors to add to the system that can be filled by "
"objects which compute residuals and Jacobians (Kernels, "
"BCs, etc.) by setting tags on them.");

params.addParam<std::vector<TagName>>("extra_tag_matrices",
"Extra matrices to add to the system that can be filled "
"by objects which compute residuals and Jacobians "
"(Kernels, BCs, etc.) by setting tags on them.");

return params;
}

CreateProblemAction::CreateProblemAction(InputParameters parameters)
: MooseObjectAction(parameters),
_blocks(getParam<std::vector<SubdomainName>>("block")),
_coord_sys(getParam<MultiMooseEnum>("coord_type"))
CreateProblemAction::CreateProblemAction(InputParameters parameters) : MooseObjectAction(parameters)
{
}

Expand All @@ -74,77 +36,23 @@ CreateProblemAction::act()
// build the problem only if we have mesh
if (_mesh.get() != NULL)
{
{
_moose_object_pars.set<MooseMesh *>("mesh") = _mesh.get();
_moose_object_pars.set<bool>("use_nonlinear") = _app.useNonlinear();

_problem =
_factory.create<FEProblemBase>(_type, getParam<std::string>("name"), _moose_object_pars);
if (!_problem.get())
mooseError("Problem has to be of a FEProblemBase type");

// if users provide a problem type, the type has to be an EigenProblem or its derived subclass
// when uing an eigen executioner
if (_app.useEigenvalue() && _type != "EigenProblem" &&
!(std::dynamic_pointer_cast<EigenProblem>(_problem)))
mooseError("Problem has to be of a EigenProblem (or derived subclass) type when using "
"eigen executioner");
}
// set up the problem
_problem->setCoordSystem(_blocks, _coord_sys);
_problem->setAxisymmetricCoordAxis(getParam<MooseEnum>("rz_coord_axis"));
_problem->setKernelCoverageCheck(getParam<bool>("kernel_coverage_check"));
_problem->setMaterialCoverageCheck(getParam<bool>("material_coverage_check"));
_problem->setParallelBarrierMessaging(getParam<bool>("parallel_barrier_messaging"));

if (isParamValid("restart_file_base"))
{
std::string restart_file_base = getParam<FileNameNoExtension>("restart_file_base");

std::size_t slash_pos = restart_file_base.find_last_of("/");
std::string path = restart_file_base.substr(0, slash_pos);
std::string file = restart_file_base.substr(slash_pos + 1);
// when this action is built by parser with Problem input block, this action
// must act i.e. create a problem. Thus if a problem has been created, it will error out.
if (_problem)
mooseError("Trying to build a problem but problem has already existed");

/**
* If the user specified LATEST as the file in their directory path, find the file with the
* latest timestep and the largest serial number.
*/
if (file == "LATEST")
{
std::list<std::string> dir_list(1, path);
std::list<std::string> files = MooseUtils::getFilesInDirs(dir_list);
restart_file_base = MooseUtils::getLatestAppCheckpointFileBase(files);
_moose_object_pars.set<MooseMesh *>("mesh") = _mesh.get();
_moose_object_pars.set<bool>("use_nonlinear") = _app.useNonlinear();

if (restart_file_base == "")
mooseError("Unable to find suitable restart file");
}
// we can change the type only because FEProblem and EigenProblem have the same valid parameters.
// Ideally, type should be required but it will require large change on existing files.
if (_app.useEigenvalue() && !_pars.isParamSetByUser("type"))
_type = "EigenProblem";

_console << "\nUsing " << restart_file_base << " for restart.\n\n";
_problem->setRestartFile(restart_file_base);
}
_problem =
_factory.create<FEProblemBase>(_type, getParam<std::string>("name"), _moose_object_pars);

// Create etra vectors and matrices if any
CreateTagVectors();
}
}

void
CreateProblemAction::CreateTagVectors()
{
// add vectors and their tags to system
auto & vectors = getParam<std::vector<TagName>>("extra_tag_vectors");
auto & nl = _problem->getNonlinearSystemBase();
for (auto & vector : vectors)
{
auto tag = _problem->addVectorTag(vector);
nl.addVector(tag, false, GHOSTED);
}

// add matrices and their tags
auto & matrices = getParam<std::vector<TagName>>("extra_tag_matrices");
for (auto & matrix : matrices)
{
auto tag = _problem->addMatrixTag(matrix);
nl.addMatrix(tag);
if (!_problem.get())
mooseError("Problem has to be of a FEProblemBase type");
}
}
69 changes: 69 additions & 0 deletions framework/src/actions/CreateProblemDefaultAction.C
@@ -0,0 +1,69 @@
//* 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 "CreateProblemDefaultAction.h"

#include "Factory.h"
#include "FEProblem.h"
#include "EigenProblem.h"
#include "NonlinearSystemBase.h"
#include "MooseApp.h"
#include "CreateExecutionerAction.h"

registerMooseAction("MooseApp", CreateProblemDefaultAction, "create_problem_default");

template <>
InputParameters
validParams<CreateProblemDefaultAction>()
{
InputParameters params = validParams<Action>();
params.addParam<bool>("solve",
true,
"Whether or not to actually solve the Nonlinear system. "
"This is handy in the case that all you want to do is "
"execute AuxKernels, Transfers, etc. without actually "
"solving anything");
return params;
}

CreateProblemDefaultAction::CreateProblemDefaultAction(InputParameters parameters)
: Action(parameters)
{
}

void
CreateProblemDefaultAction::act()
{
// act only if we have mesh
if (_mesh.get() != NULL)
{
// Make sure the problem hasn't already been created elsewhere
if (!_problem)
{
std::string type;
if (_app.useEigenvalue())
type = "EigenProblem";
else
type = "FEProblem";
auto params = _factory.getValidParams(type);

params.set<MooseMesh *>("mesh") = _mesh.get();
params.set<bool>("use_nonlinear") = _app.useNonlinear();
params.set<bool>("solve") = getParam<bool>("solve");

_problem = _factory.create<FEProblemBase>(type, "MOOSE Problem", params);
}
else
{
if (_app.useEigenvalue() && !(std::dynamic_pointer_cast<EigenProblem>(_problem)))
mooseError("Problem has to be of a EigenProblem (or derived subclass) type when using "
"eigen executioner");
}
}
}
20 changes: 0 additions & 20 deletions framework/src/actions/DetermineSystemType.C
Expand Up @@ -35,27 +35,7 @@ DetermineSystemType::act()
if (_moose_object_pars.isParamValid("_eigen") && _moose_object_pars.get<bool>("_eigen"))
_app.useNonlinear() = false;

auto _action_params = _action_factory.getValidParams("CreateProblemAction");

if (_moose_object_pars.isParamValid("_use_eigen_value") &&
_moose_object_pars.get<bool>("_use_eigen_value"))
{
_app.useEigenvalue() = true;
_action_params.set<std::string>("type") = "EigenProblem";
}
else
{
_action_params.set<std::string>("type") = "FEProblem";
}

// if we have Problem block in input file, "CreateProblemAction" will be handled by parser
if (_awh.hasActions("create_problem"))
return;

// Create "CreateProblemAction"
auto action = _action_factory.create(
"CreateProblemAction", _action_params.get<std::string>("type"), _action_params);

// Add the action to the warehouse
_awh.addActionBlock(action);
}
4 changes: 4 additions & 0 deletions framework/src/base/Moose.C
Expand Up @@ -187,6 +187,8 @@ addActionTypes(Syntax & syntax)
// Output related actions
registerTask("setup_material_output", true);
registerTask("check_output", true);
registerTask("create_problem_default", true);
registerTask("create_problem_complete", false);

/**************************/
/****** Dependencies ******/
Expand Down Expand Up @@ -218,6 +220,8 @@ addActionTypes(Syntax & syntax)
"(setup_mesh_complete)"
"(determine_system_type)"
"(create_problem)"
"(create_problem_default)"
"(create_problem_complete)"
"(setup_postprocessor_data)"
"(setup_time_integrator)"
"(setup_executioner)"
Expand Down
10 changes: 3 additions & 7 deletions framework/src/base/MooseApp.C
Expand Up @@ -1507,16 +1507,12 @@ MooseApp::createMinimalApp()
// Problem
{
// Build the Action parameters
InputParameters action_params = _action_factory.getValidParams("CreateProblemAction");
action_params.set<std::string>("type") = "FEProblem";
InputParameters action_params = _action_factory.getValidParams("CreateProblemDefaultAction");
action_params.set<bool>("solve") = false;

// Create the action
std::shared_ptr<MooseObjectAction> action = std::static_pointer_cast<MooseObjectAction>(
_action_factory.create("CreateProblemAction", "Problem", action_params));

// Set the object parameters
InputParameters & params = action->getObjectParams();
params.set<bool>("solve") = false;
_action_factory.create("CreateProblemDefaultAction", "Problem", action_params));

// Add Action to the warehouse
_action_warehouse.addActionBlock(action);
Expand Down
3 changes: 3 additions & 0 deletions framework/src/problems/DumpObjectsProblem.C
Expand Up @@ -35,6 +35,9 @@ DumpObjectsProblem::DumpObjectsProblem(const InputParameters & parameters)
_nl = _nl_sys;
_aux = std::make_shared<AuxiliarySystem>(*this, "aux0");
newAssemblyArray(*_nl_sys);

// Create etra vectors and matrices if any
CreateTagVectors();
}

void
Expand Down
3 changes: 3 additions & 0 deletions framework/src/problems/EigenProblem.C
Expand Up @@ -59,6 +59,9 @@ EigenProblem::EigenProblem(const InputParameters & parameters)
#else
mooseError("Need to install SLEPc to solve eigenvalue problems, please reconfigure\n");
#endif /* LIBMESH_HAVE_SLEPC */

// Create etra vectors and matrices if any
CreateTagVectors();
}

#if LIBMESH_HAVE_SLEPC
Expand Down
3 changes: 3 additions & 0 deletions framework/src/problems/ExternalProblem.C
Expand Up @@ -38,6 +38,9 @@ ExternalProblem::ExternalProblem(const InputParameters & parameters) : FEProblem
* Variables, which will be used in the external problem.
*/
newAssemblyArray(*_nl);

// Create etra vectors and matrices if any
CreateTagVectors();
}

void
Expand Down
3 changes: 3 additions & 0 deletions framework/src/problems/FEProblem.C
Expand Up @@ -39,6 +39,9 @@ FEProblem::FEProblem(const InputParameters & parameters)
initNullSpaceVectors(parameters, *_nl_sys);

_eq.parameters.set<FEProblem *>("_fe_problem") = this;

// Create etra vectors and matrices if any
CreateTagVectors();
}

void
Expand Down

0 comments on commit b61de47

Please sign in to comment.