Skip to content
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

Implementation of nodal source terms #1977

Merged
merged 12 commits into from
Nov 9, 2017
Merged
Original file line number Diff line number Diff line change
@@ -1 +1 @@
The name of the on which the boundary condition is defined.
The name of the geometry on which the boundary condition is defined.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Contains source terms for the process variable.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Declares a source term to be associated to a node.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The value for the nodal source term.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Defines a source term for a process variable.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
For the multi-component process variables specifies the component of the
source term. The component ids start with 0. For single-component
variables this is optional and defaults to 0.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
The name of the geometrical set (see \ref ogs_file_param__gml__name) in which
the \ref
ogs_file_param__prj__process_variables__process_variable__source_terms__source_term__geometry
"geometry" is defined.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The name of the geometry on which the source term is defined.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Sets the type of the source term.
49 changes: 49 additions & 0 deletions MeshGeoToolsLib/CreateSearchLength.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* @file
* @copyright
* Copyright (c) 2012-2017, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/LICENSE.txt
*/

#include "CreateSearchLength.h"

#include "BaseLib/ConfigTree.h"
#include "BaseLib/Error.h"

#include "MeshGeoToolsLib/HeuristicSearchLength.h"
#include "MeshGeoToolsLib/SearchLength.h"

namespace MeshGeoToolsLib
{
std::unique_ptr<MeshGeoToolsLib::SearchLength> createSearchLengthAlgorithm(
BaseLib::ConfigTree const& external_config, MeshLib::Mesh const& mesh)
{
boost::optional<BaseLib::ConfigTree> config =
//! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__search_length_algorithm}
external_config.getConfigSubtreeOptional("search_length_algorithm");

if (!config)
return std::unique_ptr<MeshGeoToolsLib::SearchLength>{
new MeshGeoToolsLib::SearchLength()};

//! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__search_length_algorithm__type}
std::string const type = config->getConfigParameter<std::string>("type");

if (type == "fixed")
{
//! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__search_length_algorithm__fixed__value}
double const length = config->getConfigParameter<double>("value");
return std::unique_ptr<MeshGeoToolsLib::SearchLength>{
new MeshGeoToolsLib::SearchLength(length)};
}
if (type == "heuristic")
{
return std::unique_ptr<MeshGeoToolsLib::HeuristicSearchLength>{
new MeshGeoToolsLib::HeuristicSearchLength(mesh)};
}
OGS_FATAL("Unknown search length algorithm type '%s'.", type.c_str());
}

} // end namespace MeshGeoToolsLib
42 changes: 11 additions & 31 deletions MeshGeoToolsLib/CreateSearchLength.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,40 +13,20 @@

#include <memory>

#include "BaseLib/ConfigTree.h"
namespace BaseLib
{
class ConfigTree;
}

#include "MeshGeoToolsLib/HeuristicSearchLength.h"
#include "MeshGeoToolsLib/SearchLength.h"
namespace MeshLib
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. This is much nicer because of the removed includes and the fwd-decls.

{
class Mesh;
}

namespace MeshGeoToolsLib
{
std::unique_ptr<MeshGeoToolsLib::SearchLength> createSearchLengthAlgorithm(
BaseLib::ConfigTree const& external_config, MeshLib::Mesh const& mesh)
{
boost::optional<BaseLib::ConfigTree> config =
//! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__search_length_algorithm}
external_config.getConfigSubtreeOptional("search_length_algorithm");

if (!config)
return std::unique_ptr<MeshGeoToolsLib::SearchLength>{
new MeshGeoToolsLib::SearchLength()};

//! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__search_length_algorithm__type}
std::string const type = config->getConfigParameter<std::string>("type");

if (type == "fixed")
{
//! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__search_length_algorithm__fixed__value}
double const length = config->getConfigParameter<double>("value");
return std::unique_ptr<MeshGeoToolsLib::SearchLength>{
new MeshGeoToolsLib::SearchLength(length)};
}
if (type == "heuristic")
{
return std::unique_ptr<MeshGeoToolsLib::HeuristicSearchLength>{
new MeshGeoToolsLib::HeuristicSearchLength(mesh)};
}
OGS_FATAL("Unknown search length algorithm type '%s'.", type.c_str());
}
class SearchLength;

std::unique_ptr<MeshGeoToolsLib::SearchLength> createSearchLengthAlgorithm(
BaseLib::ConfigTree const& external_config, MeshLib::Mesh const& mesh);
} // end namespace MeshGeoToolsLib
1 change: 1 addition & 0 deletions ProcessLib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ APPEND_SOURCE_FILES(SOURCES Parameter)
APPEND_SOURCE_FILES(SOURCES PhaseField)
APPEND_SOURCE_FILES(SOURCES RichardsFlow)
APPEND_SOURCE_FILES(SOURCES SmallDeformation)
APPEND_SOURCE_FILES(SOURCES SourceTerms)
APPEND_SOURCE_FILES(SOURCES TES)
APPEND_SOURCE_FILES(SOURCES ThermoMechanics)
APPEND_SOURCE_FILES(SOURCES TwoPhaseFlowWithPP)
Expand Down
103 changes: 103 additions & 0 deletions ProcessLib/GroundwaterFlow/Tests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -597,3 +597,106 @@ AddTest(
DIFF_DATA
expected_dirichlet_nonuniform_pcs_0_ts_1_t_1.000000.vtu dirichlet_nonuniform_pcs_0_ts_1_t_1.000000.vtu pressure pressure
)

# tests for nodal source term implementation
# For the special setup with a dirac source term at position (xi, eta) the
# analytical solution in 2 dimensions is valid:
# u(x,y) = ln(sqrt((x-xi)^2+(y-eta)^2))/(2 * Pi)
AddTest(
NAME GroundWaterFlowProcess_NodalSourceTerm_circle_1e1
PATH Elliptic/circle_radius_1
EXECUTABLE ogs
EXECUTABLE_ARGS circle_1e1_axi.prj
WRAPPER time
TESTER vtkdiff
REQUIREMENTS NOT (OGS_USE_LIS OR OGS_USE_MPI)
ABSTOL 0.7 RELTOL 1e-16
DIFF_DATA
line_1_lines_1e1_expected.vtu circle_1e1_axi_pcs_0_ts_1_t_1.000000.vtu analytical_solution pressure
VIS circle_1e1_axi_pcs_0_ts_1_t_1.000000.vtu
)

AddTest(
NAME GroundWaterFlowProcess_NodalSourceTerm_circle_1e2
PATH Elliptic/circle_radius_1
EXECUTABLE ogs
EXECUTABLE_ARGS circle_1e2_axi.prj
WRAPPER time
TESTER vtkdiff
REQUIREMENTS NOT (OGS_USE_LIS OR OGS_USE_MPI)
ABSTOL 1.1 RELTOL 1e-16
DIFF_DATA
line_1_lines_1e2_expected.vtu circle_1e2_axi_pcs_0_ts_1_t_1.000000.vtu analytical_solution pressure
VIS circle_1e2_axi_pcs_0_ts_1_t_1.000000.vtu
)

AddTest(
NAME GroundWaterFlowProcess_NodalSourceTerm_circle_1e3
PATH Elliptic/circle_radius_1
EXECUTABLE ogs
EXECUTABLE_ARGS circle_1e3_axi.prj
WRAPPER time
TESTER vtkdiff
REQUIREMENTS NOT (OGS_USE_LIS OR OGS_USE_MPI)
ABSTOL 1.6 RELTOL 1e-16
DIFF_DATA
line_1_lines_1e3_expected.vtu circle_1e3_axi_pcs_0_ts_1_t_1.000000.vtu analytical_solution pressure
VIS circle_1e3_axi_pcs_0_ts_1_t_1.000000.vtu
)

AddTest(
NAME GroundWaterFlowProcess_NodalSourceTerm_circle_1e4
PATH Elliptic/circle_radius_1
EXECUTABLE ogs
EXECUTABLE_ARGS circle_1e4_axi.prj
WRAPPER time
TESTER vtkdiff
REQUIREMENTS NOT (OGS_USE_LIS OR OGS_USE_MPI)
ABSTOL 1.8 RELTOL 1e-16
DIFF_DATA
line_1_lines_1e4_expected.vtu circle_1e4_axi_pcs_0_ts_1_t_1.000000.vtu analytical_solution pressure
VIS circle_1e4_axi_pcs_0_ts_1_t_1.000000.vtu
)

AddTest(
NAME LARGE_GroundWaterFlowProcess_NodalSourceTerm_circle_1e5
PATH Elliptic/circle_radius_1
EXECUTABLE ogs
EXECUTABLE_ARGS circle_1e5_axi.prj
WRAPPER time
TESTER vtkdiff
REQUIREMENTS NOT (OGS_USE_LIS OR OGS_USE_MPI)
ABSTOL 2.15 RELTOL 1e-16
DIFF_DATA
line_1_lines_1e5_expected.vtu circle_1e5_axi_pcs_0_ts_1_t_1.000000.vtu analytical_solution pressure
VIS circle_1e5_axi_pcs_0_ts_1_t_1.000000.vtu
)

AddTest(
NAME LARGE_GroundWaterFlowProcess_NodalSourceTerm_circle_1e6
PATH Elliptic/circle_radius_1
EXECUTABLE ogs
EXECUTABLE_ARGS circle_1e6_axi.prj
WRAPPER time
TESTER vtkdiff
REQUIREMENTS NOT (OGS_USE_LIS OR OGS_USE_MPI)
ABSTOL 2.52 RELTOL 1e-16
DIFF_DATA
line_1_lines_1e6_expected.vtu circle_1e6_axi_pcs_0_ts_1_t_1.000000.vtu analytical_solution pressure
VIS circle_1e6_axi_pcs_0_ts_1_t_1.000000.vtu
)

AddTest(
NAME LARGE_GroundWaterFlowProcess_NodalSourceTerm_square_1e6
PATH Elliptic/square_1x1_GroundWaterFlow
EXECUTABLE ogs
EXECUTABLE_ARGS square_1e6_with_nodal_sources.prj
WRAPPER time
TESTER vtkdiff
REQUIREMENTS NOT (OGS_USE_LIS OR OGS_USE_MPI)
ABSTOL 1.41 RELTOL 1e-16
DIFF_DATA
square_1x1_quad_1e6_nodal_sources_expected.vtu square_1e6_pcs_0_ts_1_t_1.000000.vtu analytical_solution pressure
VIS square_1e6_pcs_0_ts_1_t_1.000000.vtu
)

18 changes: 18 additions & 0 deletions ProcessLib/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,19 @@ void Process::initialize()
DBUG("Initialize boundary conditions.");
_boundary_conditions.addBCsForProcessVariables(
_process_variables, *_local_to_global_index_map, _integration_order);

for (int variable_id = 0;
variable_id < static_cast<int>(_process_variables.size());
++variable_id)
{
ProcessVariable& pv = _process_variables[variable_id];
auto sts =
pv.createSourceTerms(*_local_to_global_index_map, variable_id,
_integration_order);

std::move(sts.begin(), sts.end(),
std::back_inserter(_source_terms));
}
}

void Process::setInitialConditions(double const t, GlobalVector& x)
Expand Down Expand Up @@ -128,6 +141,11 @@ void Process::assemble(const double t, GlobalVector const& x, GlobalMatrix& M,
assembleConcreteProcess(t, x, M, K, b);

_boundary_conditions.applyNaturalBC(t, x, K, b);

for (auto const& st : _source_terms)
{
st->integrateNodalSourceTerm(t, b);
}
}

void Process::assembleWithJacobian(const double t, GlobalVector const& x,
Expand Down
2 changes: 2 additions & 0 deletions ProcessLib/Process.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "NumLib/ODESolver/TimeDiscretization.h"
#include "NumLib/NamedFunctionCaller.h"
#include "ProcessLib/BoundaryCondition/BoundaryConditionCollection.h"
#include "ProcessLib/SourceTerms/NodalSourceTerm.h"
#include "ProcessLib/Parameter/Parameter.h"

#include "ExtrapolatorData.h"
Expand Down Expand Up @@ -218,6 +219,7 @@ class Process
std::vector<std::reference_wrapper<ProcessVariable>> _process_variables;

BoundaryConditionCollection _boundary_conditions;
std::vector<std::unique_ptr<NodalSourceTerm>> _source_terms;

ExtrapolatorData _extrapolator_data;
};
Expand Down
66 changes: 64 additions & 2 deletions ProcessLib/ProcessVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ ProcessVariable::ProcessVariable(
//! \ogs_file_param{prj__process_variables__process_variable__initial_condition}
config.getConfigParameter<std::string>("initial_condition"),
parameters, _n_components)),
_bc_builder(std::make_unique<BoundaryConditionBuilder>())
_bc_builder(std::make_unique<BoundaryConditionBuilder>()),
_source_term_builder(std::make_unique<SourceTermBuilder>())
{
DBUG("Constructing process variable %s", _name.c_str());

Expand Down Expand Up @@ -82,6 +83,49 @@ ProcessVariable::ProcessVariable(
} else {
INFO("No boundary conditions found.");
}

// Source terms
//! \ogs_file_param{prj__process_variables__process_variable__source_terms}
if (auto sts_config = config.getConfigSubtreeOptional("source_terms"))
{
for (auto st_config :
//! \ogs_file_param{prj__process_variables__process_variable__source_terms__source_term}
sts_config->getConfigSubtreeList("source_term"))
{
auto const geometrical_set_name =
//! \ogs_file_param{prj__process_variables__process_variable__source_terms__source_term__geometrical_set}
st_config.getConfigParameter<std::string>("geometrical_set");
auto const geometry_name =
//! \ogs_file_param{prj__process_variables__process_variable__source_terms__source_term__geometry}
st_config.getConfigParameter<std::string>("geometry");

GeoLib::GeoObject const* const geometry =
geometries.getGeoObject(geometrical_set_name, geometry_name);

if (! geometry)
OGS_FATAL(
"No geometry with name `%s' has been found in the "
"geometrical set `%s'.",
geometry_name.c_str(), geometrical_set_name.c_str());

DBUG(
"Found geometry type \"%s\"",
GeoLib::convertGeoTypeToString(geometry->getGeoType()).c_str());

auto component_id =
//! \ogs_file_param{prj__process_variables__process_variable__source_terms__source_term__component}
st_config.getConfigParameterOptional<int>("component");

if (!component_id && _n_components == 1)
// default value for single component vars.
component_id = 0;

_source_term_configs.emplace_back(std::move(st_config), *geometry,
component_id);
}
} else {
INFO("No source terms found.");
}
}

ProcessVariable::ProcessVariable(ProcessVariable&& other)
Expand All @@ -91,7 +135,9 @@ ProcessVariable::ProcessVariable(ProcessVariable&& other)
_shapefunction_order(other._shapefunction_order),
_initial_condition(std::move(other._initial_condition)),
_bc_configs(std::move(other._bc_configs)),
_bc_builder(std::move(other._bc_builder))
_bc_builder(std::move(other._bc_builder)),
_source_term_configs(std::move(other._source_term_configs)),
_source_term_builder(std::move(other._source_term_builder))
{
}

Expand Down Expand Up @@ -128,4 +174,20 @@ ProcessVariable::createBoundaryConditions(
return bcs;
}

std::vector<std::unique_ptr<NodalSourceTerm>>
ProcessVariable::createSourceTerms(
const NumLib::LocalToGlobalIndexMap& dof_table,
const int variable_id,
unsigned const integration_order)
{
std::vector<std::unique_ptr<NodalSourceTerm>> source_terms;

for (auto& config : _source_term_configs)
source_terms.emplace_back(_source_term_builder->createSourceTerm(
config, dof_table, _mesh, variable_id, integration_order,
_shapefunction_order));

return source_terms;
}

} // namespace ProcessLib
Loading