Commit 8837fa36 authored by wenqing's avatar wenqing

temp

parent 023b620c
......@@ -84,6 +84,126 @@ void CentralDifferencesJacobianAssembler::assembleWithJacobian(
_local_x_perturbed_data[i] = local_x_data[i];
if (!local_M_data.empty())
{
auto const local_M_p =
MathLib::toMatrix(local_M_data, num_r_c, num_r_c);
auto const local_M_m =
MathLib::toMatrix(_local_M_data, num_r_c, num_r_c);
local_Jac.col(i).noalias() +=
// dM/dxi * x_dot
(local_M_p - local_M_m) * local_xdot / (2.0 * eps);
local_M_data.clear();
_local_M_data.clear();
}
if (!local_K_data.empty())
{
auto const local_K_p =
MathLib::toMatrix(local_K_data, num_r_c, num_r_c);
auto const local_K_m =
MathLib::toMatrix(_local_K_data, num_r_c, num_r_c);
local_Jac.col(i).noalias() +=
// dK/dxi * x
(local_K_p - local_K_m) * local_x / (2.0 * eps);
local_K_data.clear();
_local_K_data.clear();
}
if (!local_b_data.empty())
{
auto const local_b_p =
MathLib::toVector<Eigen::VectorXd>(local_b_data, num_r_c);
auto const local_b_m =
MathLib::toVector<Eigen::VectorXd>(_local_b_data, num_r_c);
local_Jac.col(i).noalias() -=
// db/dxi
(local_b_p - local_b_m) / (2.0 * eps);
local_b_data.clear();
_local_b_data.clear();
}
}
// Assemble with unperturbed local x.
local_assembler.assemble(t, dt, local_x_data, local_xdot_data, local_M_data,
local_K_data, local_b_data);
// Compute remaining terms of the Jacobian.
if (dxdot_dx != 0.0 && !local_M_data.empty())
{
auto local_M = MathLib::toMatrix(local_M_data, num_r_c, num_r_c);
local_Jac.noalias() += local_M * dxdot_dx;
}
if (dx_dx != 0.0 && !local_K_data.empty())
{
auto local_K = MathLib::toMatrix(local_K_data, num_r_c, num_r_c);
local_Jac.noalias() += local_K * dx_dx;
}
}
void CentralDifferencesJacobianAssembler::
assembleWithJacobianForStaggeredScheme(
LocalAssemblerInterface& local_assembler, double const t,
double const dt, Eigen::VectorXd const& local_x,
Eigen::VectorXd const& local_xdot, const double dxdot_dx,
const double dx_dx, int const process_id,
std::vector<double>& local_M_data, std::vector<double>& local_K_data,
std::vector<double>& local_b_data, std::vector<double>& local_Jac_data)
{
// TODO do not check in every call.
if (local_x_data.size() % _absolute_epsilons.size() != 0)
{
OGS_FATAL(
"The number of specified epsilons ({:d}) and the number of local "
"d.o.f.s ({:d}) do not match, i.e., the latter is not divisable by "
"the former.",
_absolute_epsilons.size(), local_x_data.size());
}
auto const num_r_c =
static_cast<Eigen::MatrixXd::Index>(local_x_data.size());
auto const local_x =
MathLib::toVector<Eigen::VectorXd>(local_x_data, num_r_c);
auto const local_xdot =
MathLib::toVector<Eigen::VectorXd>(local_xdot_data, num_r_c);
auto local_Jac =
MathLib::createZeroedMatrix(local_Jac_data, num_r_c, num_r_c);
_local_x_perturbed_data = local_x_data;
auto const num_dofs_per_component =
local_x_data.size() / _absolute_epsilons.size();
// Residual res := M xdot + K x - b
// Computing Jac := dres/dx
// = M dxdot/dx + dM/dx xdot + K dx/dx + dK/dx x - db/dx
// (Note: dM/dx and dK/dx actually have the second and
// third index transposed.)
// The loop computes the dM/dx, dK/dx and db/dx terms, the rest is computed
// afterwards.
for (Eigen::MatrixXd::Index i = 0; i < num_r_c; ++i)
{
// assume that local_x_data is ordered by component.
auto const component = i / num_dofs_per_component;
auto const eps = _absolute_epsilons[component];
_local_x_perturbed_data[i] += eps;
local_assembler.assemble(t, dt, _local_x_perturbed_data,
local_xdot_data, local_M_data, local_K_data,
local_b_data);
local_assembler.assembleForStaggeredScheme(
t, dt, local_x, local_xdot, process_id,
std::vector<double> & local_M_data,
std::vector<double> & local_K_data,
std::vector<double> & local_b_data)
_local_x_perturbed_data[i] = local_x_data[i] - eps;
local_assembler.assemble(t, dt, _local_x_perturbed_data,
local_xdot_data, _local_M_data, _local_K_data,
_local_b_data);
_local_x_perturbed_data[i] = local_x_data[i];
if (!local_M_data.empty()) {
auto const local_M_p =
MathLib::toMatrix(local_M_data, num_r_c, num_r_c);
......
......@@ -60,6 +60,15 @@ public:
std::vector<double>& local_b_data,
std::vector<double>& local_Jac_data) override;
void assembleWithJacobianForStaggeredScheme(
LocalAssemblerInterface& local_assembler, double const t,
double const dt, Eigen::VectorXd const& local_x,
Eigen::VectorXd const& local_xdot, const double dxdot_dx,
const double dx_dx, int const process_id,
std::vector<double>& local_M_data, std::vector<double>& local_K_data,
std::vector<double>& local_b_data,
std::vector<double>& local_Jac_data) override;
private:
std::vector<double> const _absolute_epsilons;
......
......@@ -25,6 +25,7 @@
#include "NonisothermalRichardsFlowMechanicsStaggerdTHcM.h"
#include "NonisothermalRichardsFlowMechanicsStaggerdTcHcM.h"
#include "ParameterLib/Utils.h"
#include "ProcessLib/CreateJacobianAssembler.h"
#include "ProcessLib/Output/CreateSecondaryVariables.h"
#include "ProcessLib/RichardsMechanics/RichardsMechanicsProcessData.h"
#include "ProcessLib/Utils/ProcessUtils.h"
......@@ -255,12 +256,19 @@ std::unique_ptr<Process> createNonisothermalRichardsFlowMechanicsProcess(
}
else if ((staggered_scheme && (*staggered_scheme == "staggered_T_H_M")))
{
auto jacobian_assembler_for_richards =
ProcessLib::createJacobianAssembler(
//! \ogs_file_param{prj__processes__process__NONISOTHERMAL_RICHARDSFLOW_MECHANICS__numerical_jacobian_assembler_richards}
config.getConfigSubtreeOptional(
"numerical_jacobian_assembler_for_richards"));
DataOfStaggeredTcHcM data_of_staggeredTcHcM{
0, 1, 2, has_vapor_diffusion, use_fixed_stress_rate_split};
return std::make_unique<
NonisothermalRichardsFlowMechanicsStaggerdTcHcM<DisplacementDim>>(
std::move(name), mesh, std::move(jacobian_assembler), parameters,
std::move(name), mesh, std::move(jacobian_assembler),
std::move(jacobian_assembler_for_richards), parameters,
integration_order, std::move(process_variables),
std::move(process_data), std::move(secondary_variables),
std::move(data_of_staggeredTcHcM));
......
......@@ -33,6 +33,8 @@ NonisothermalRichardsFlowMechanicsStaggerdTcHcM<DisplacementDim>::
MeshLib::Mesh& mesh,
std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&&
jacobian_assembler,
std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&&
jacobian_assembler_for_richards,
std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const&
parameters,
unsigned const integration_order,
......@@ -55,7 +57,8 @@ NonisothermalRichardsFlowMechanicsStaggerdTcHcM<DisplacementDim>::
.getShapeFunctionOrder() ==
this->_process_variables[data_of_staggeredTcHcM_.M_process_id][0]
.get()
.getShapeFunctionOrder())
.getShapeFunctionOrder()),
global_assembler_for_richards_(std::move(jacobian_assembler_for_richards))
{
}
......@@ -236,18 +239,37 @@ void NonisothermalRichardsFlowMechanicsStaggerdTcHcM<DisplacementDim>::
const double dx_dx, int const process_id, GlobalMatrix& M,
GlobalMatrix& K, GlobalVector& b, GlobalMatrix& Jac)
{
INFO(
"Assemble the equations for the mechanical process (M) of "
"NonisothermalRichardsFlowMechanics");
ProcessLib::ProcessVariable const& pv =
this->getProcessVariables(process_id)[0];
auto const dof_tables = getDOFTables();
GlobalExecutor::executeSelectedMemberDereferenced(
this->_global_assembler, &VectorMatrixAssembler::assembleWithJacobian,
this->local_assemblers_, pv.getActiveElementIDs(), dof_tables, t, dt, x,
xdot, dxdot_dx, dx_dx, process_id, M, K, b, Jac);
if (process_id == data_of_staggeredTcHcM_.H_process_id)
{
INFO(
"Assemble the equations for the hydraulic process (H) of "
"NonisothermalRichardsFlowMechanics");
GlobalExecutor::executeSelectedMemberDereferenced(
global_assembler_for_richards_,
&VectorMatrixAssembler::assembleWithJacobian,
this->local_assemblers_, pv.getActiveElementIDs(), dof_tables, t,
dt, x, xdot, dxdot_dx, dx_dx, process_id, M, K, b, Jac);
return;
}
if (process_id == data_of_staggeredTcHcM_.M_process_id)
{
INFO(
"Assemble the equations for the mechanical process (M) of "
"NonisothermalRichardsFlowMechanics");
GlobalExecutor::executeSelectedMemberDereferenced(
this->_global_assembler,
&VectorMatrixAssembler::assembleWithJacobian,
this->local_assemblers_, pv.getActiveElementIDs(), dof_tables, t,
dt, x, xdot, dxdot_dx, dx_dx, process_id, M, K, b, Jac);
}
}
template <int DisplacementDim>
......
......@@ -31,6 +31,8 @@ public:
MeshLib::Mesh& mesh,
std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&&
jacobian_assembler,
std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&&
jacobian_assembler_for_richards,
std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const&
parameters,
unsigned const integration_order,
......@@ -90,6 +92,8 @@ private:
/// Falg to indicate whether T, H, M use the same element order.
bool const use_unique_interpolation_order_;
VectorMatrixAssembler global_assembler_for_richards_;
using LocalAssemblerIF =
RichardsMechanics::LocalAssemblerInterface<DisplacementDim>;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment