diff --git a/Documentation/ProjectFile/prj/processes/process/HEAT_TRANSPORT_BHE/t_linear.md b/Documentation/ProjectFile/prj/processes/process/HEAT_TRANSPORT_BHE/t_linear.md new file mode 100644 index 00000000000..c75385a76ff --- /dev/null +++ b/Documentation/ProjectFile/prj/processes/process/HEAT_TRANSPORT_BHE/t_linear.md @@ -0,0 +1 @@ +The default setting is false. When activated, non-linear iterations will be turned off. The simulation will just go through a single iteration within a time step. If it's set to true, the **\** option must be also set to true. Only when fluid properties does not change much with temperature, this feature can be activated. The effect of skipping the non-linear iteration is much faster simulation speed. diff --git a/Documentation/ProjectFile/prj/processes/process/HEAT_TRANSPORT_BHE/t_use_algebraic_bc.md b/Documentation/ProjectFile/prj/processes/process/HEAT_TRANSPORT_BHE/t_use_algebraic_bc.md new file mode 100644 index 00000000000..b735f6a1fa8 --- /dev/null +++ b/Documentation/ProjectFile/prj/processes/process/HEAT_TRANSPORT_BHE/t_use_algebraic_bc.md @@ -0,0 +1 @@ +The default setting is false. When algebraic boundary condition is activated, the inflow temperatures at the top and bottom of the BHE are no longer imposed as a Dirichlet type boundary condition. Instead, the linear equation system will be enlarged to accommodate the numerical constrains. The effect of this feature is to accelerate BHE simulations. diff --git a/Documentation/ProjectFile/prj/processes/process/HEAT_TRANSPORT_BHE/t_weighting_factor.md b/Documentation/ProjectFile/prj/processes/process/HEAT_TRANSPORT_BHE/t_weighting_factor.md new file mode 100644 index 00000000000..b557a842c7f --- /dev/null +++ b/Documentation/ProjectFile/prj/processes/process/HEAT_TRANSPORT_BHE/t_weighting_factor.md @@ -0,0 +1 @@ +This value is the weighting factor used to impose an algebraic boundary condition in the **HeatTransportBHE** process. The default value is 100. This value is only effective, when the option **\** is set to true. This value is multiplied with the max value of the column wise inner product and then imposed in the additional rows at the end of the linear equation system, so that the unknown temperatures at the top and bottom of the BHE are imposed with certain desired values. diff --git a/MathLib/LinAlg/LinAlg.cpp b/MathLib/LinAlg/LinAlg.cpp index 5e688a3fd1e..8be69e83804 100644 --- a/MathLib/LinAlg/LinAlg.cpp +++ b/MathLib/LinAlg/LinAlg.cpp @@ -167,6 +167,34 @@ void matMultAdd(PETScMatrix const& A, PETScVector const& v1, v3.getRawVector()); } +void linearSysNormalize(PETScMatrix const& /*A*/, PETScMatrix& /*new_A*/, + PETScVector const& /*b*/, PETScVector& /*new_b*/) +{ + // The following block is deactivated, because there is no tests yet for the + // normalization operation in PETSc. This will be a task for later. + /* + assert(&A != &new_A); + assert(&b != &new_b); + + PetscInt n_rows(0); + PetscInt n_cols(0); + MatGetSize(A.getRawMatrix(), &n_rows, &n_cols); + // only when A matrix is not square + if (n_rows != n_cols) + { + // new_b = A^T * b + MatMultTranspose(A.getRawMatrix(), b.getRawVector(), + new_b.getRawVector()); + // new_A = A^T * A + MatTranspose(A.getRawMatrix(), MAT_INITIAL_MATRIX, + &(new_A.getRawMatrix())); + } + */ + OGS_FATAL( + "Normalization operation is not implemented yet for PETSc library! " + "Program terminated."); +} + void finalizeAssembly(PETScMatrix& A) { A.finalizeAssembly(MAT_FINAL_ASSEMBLY); @@ -313,6 +341,25 @@ void matMultAdd(EigenMatrix const& A, EigenVector const& v1, v2.getRawVector() + A.getRawMatrix() * v1.getRawVector(); } +void linearSysNormalize(EigenMatrix const& A, EigenMatrix& new_A, + EigenVector const& b, EigenVector& new_b) +{ + // make sure that new_A and new_b are not the same memory + assert(&A != &new_A); + assert(&b != &new_b); + + if (A.getRawMatrix().rows() == A.getRawMatrix().cols()) + { + WARN( + "The number of rows and columns are the same for the LHS matrix." + "Are you sure you still need to normalize the LHS matrix and RHS " + "vector? "); + } + + new_b.getRawVector() = A.getRawMatrix().transpose() * b.getRawVector(); + new_A.getRawMatrix() = A.getRawMatrix().transpose() * A.getRawMatrix(); +} + void finalizeAssembly(EigenMatrix& x) { x.getRawMatrix().makeCompressed(); diff --git a/MathLib/LinAlg/LinAlg.h b/MathLib/LinAlg/LinAlg.h index f982306db82..206395e8f90 100644 --- a/MathLib/LinAlg/LinAlg.h +++ b/MathLib/LinAlg/LinAlg.h @@ -196,6 +196,11 @@ void matMult(PETScMatrix const& A, PETScVector const& x, PETScVector& y); void matMultAdd(PETScMatrix const& A, PETScVector const& v1, PETScVector const& v2, PETScVector& v3); +// new_A = A^T * A +// new_b = A^T * b +void linearSysNormalize(PETScMatrix const& A, PETScMatrix& new_A, + PETScVector const& b, PETScVector& new_b); + void finalizeAssembly(PETScMatrix& A); void finalizeAssembly(PETScVector& x); @@ -264,7 +269,10 @@ void matMult(EigenMatrix const& A, EigenVector const& x, EigenVector& y); // v3 = A*v1 + v2 void matMultAdd(EigenMatrix const& A, EigenVector const& v1, EigenVector const& v2, EigenVector& v3); - +// new_A = A^T * A +// new_b = A^T * b +void linearSysNormalize(EigenMatrix const& A, EigenMatrix& new_A, + EigenVector const& b, EigenVector& new_b); void finalizeAssembly(EigenMatrix& x); void finalizeAssembly(EigenVector& A); diff --git a/NumLib/ODESolver/EquationSystem.h b/NumLib/ODESolver/EquationSystem.h index 643d1bdb57a..c851ed8f92c 100644 --- a/NumLib/ODESolver/EquationSystem.h +++ b/NumLib/ODESolver/EquationSystem.h @@ -39,6 +39,15 @@ class EquationSystem */ virtual bool isLinear() const = 0; + /*! Check whether normalization of A and rhs is required. + * + * \remark + * In some processes, a normalization operation is required, to calculate + * A^T * A, and overwrite A; also calculate A^T * rhs and overwrite rhs. + * This parameter reflect whether such operation is required. + */ + virtual bool requiresNormalization() const = 0; + /*! Prepares a new iteration in the solution process of this equation. * * \param iter the current iteration number, starting from 1. diff --git a/NumLib/ODESolver/MatrixTranslator.cpp b/NumLib/ODESolver/MatrixTranslator.cpp index 5be630904e1..c86edbba043 100644 --- a/NumLib/ODESolver/MatrixTranslator.cpp +++ b/NumLib/ODESolver/MatrixTranslator.cpp @@ -43,6 +43,25 @@ void MatrixTranslatorGeneral:: NumLib::GlobalVectorProvider::provider.releaseVector(tmp); } +void MatrixTranslatorGeneral:: + normalizeAandRhs(GlobalMatrix& A, GlobalVector& b) const +{ + namespace LinAlg = MathLib::LinAlg; + + // check whether A is square? + + GlobalMatrix new_A(A); + GlobalVector new_b(b); + LinAlg::copy(A, new_A); + LinAlg::copy(b, new_b); + // rhs = A^T * rhs + // A = A^T * A + LinAlg::linearSysNormalize(A, new_A, b, new_b); + + LinAlg::copy(new_A, A); + LinAlg::copy(new_b, b); +} + void MatrixTranslatorGeneral:: computeResidual(GlobalMatrix const& M, GlobalMatrix const& K, GlobalVector const& b, double const dt, diff --git a/NumLib/ODESolver/MatrixTranslator.h b/NumLib/ODESolver/MatrixTranslator.h index b3752586c0b..60cc11dfcf5 100644 --- a/NumLib/ODESolver/MatrixTranslator.h +++ b/NumLib/ODESolver/MatrixTranslator.h @@ -49,6 +49,10 @@ class MatrixTranslator const GlobalVector& b, const GlobalVector& x_prev, GlobalVector& rhs) const = 0; + //! Computes \f$ A = A^T \cdot A \f$, and + //! also \f$ rhs = A^T \cdot rhs \f$. + virtual void normalizeAandRhs(GlobalMatrix& A, GlobalVector& b) const = 0; + /*! Computes \c res from \c M, \c K, \c b, \f$ \hat x \f$ and \f$ x_N \f$. * You might also want read the remarks on * \ref concept_time_discretization "time discretization". @@ -105,6 +109,10 @@ class MatrixTranslatorGeneral const GlobalVector& b, const GlobalVector& x_prev, GlobalVector& rhs) const override; + //! Computes \f$ A = A^T \cdot A \f$, and + //! also \f$ rhs = A^T \cdot rhs \f$. + void normalizeAandRhs(GlobalMatrix& A, GlobalVector& b) const override; + //! Computes \f$ r = M \cdot \hat x + K \cdot x_C - b \f$. void computeResidual(GlobalMatrix const& M, GlobalMatrix const& K, GlobalVector const& b, double dt, diff --git a/NumLib/ODESolver/NonlinearSolver.cpp b/NumLib/ODESolver/NonlinearSolver.cpp index 324c11905c6..59c0886b55b 100644 --- a/NumLib/ODESolver/NonlinearSolver.cpp +++ b/NumLib/ODESolver/NonlinearSolver.cpp @@ -167,6 +167,11 @@ NonlinearSolverStatus NonlinearSolver::solve( sys.assemble(x_new, x_prev, process_id); sys.getA(A); sys.getRhs(*x_prev[process_id], rhs); + + // Normalize the linear equation system, if required + if (sys.requiresNormalization()) + sys.getAandRhsNormalized(A, rhs); + INFO("[time] Assembly took {:g} s.", time_assembly.elapsed()); // Subtract non-equilibrium initial residuum if set diff --git a/NumLib/ODESolver/NonlinearSystem.h b/NumLib/ODESolver/NonlinearSystem.h index e3b20f6e12d..82d9681525e 100644 --- a/NumLib/ODESolver/NonlinearSystem.h +++ b/NumLib/ODESolver/NonlinearSystem.h @@ -121,6 +121,12 @@ class NonlinearSystem : public EquationSystem virtual void getRhs(GlobalVector const& x_prev, GlobalVector& rhs) const = 0; + //! Writes the A_transposed times A into \c A + //! and also writes A_transposed times rhs into \c rhs + //! \pre getA() and getRhs must have been called before. + virtual void getAandRhsNormalized(GlobalMatrix& A, + GlobalVector& rhs) const = 0; + //! Pre-compute known solutions and possibly store them internally. virtual void computeKnownSolutions(GlobalVector const& x, int const process_id) = 0; diff --git a/NumLib/ODESolver/TimeDiscretizedODESystem.h b/NumLib/ODESolver/TimeDiscretizedODESystem.h index 4fffd07cbcb..e93751dd9d8 100644 --- a/NumLib/ODESolver/TimeDiscretizedODESystem.h +++ b/NumLib/ODESolver/TimeDiscretizedODESystem.h @@ -120,6 +120,11 @@ class TimeDiscretizedODESystemcomputeRhs(*_M, *_K, *_b, x_prev, rhs); } + void getAandRhsNormalized(GlobalMatrix& A, GlobalVector& rhs) const override + { + _mat_trans->normalizeAandRhs(A, rhs); + } + void computeKnownSolutions(GlobalVector const& x, int const process_id) override; @@ -217,6 +227,11 @@ class TimeDiscretizedODESystem("flow_rate"); + return FixedPowerConstantFlow{flow_rate, power, refrigerant.specific_heat_capacity, refrigerant.density}; diff --git a/ProcessLib/HeatTransportBHE/BHE/FlowAndTemperatureControl.h b/ProcessLib/HeatTransportBHE/BHE/FlowAndTemperatureControl.h index b0b815a57c9..06f47752712 100644 --- a/ProcessLib/HeatTransportBHE/BHE/FlowAndTemperatureControl.h +++ b/ProcessLib/HeatTransportBHE/BHE/FlowAndTemperatureControl.h @@ -35,6 +35,7 @@ struct TemperatureCurveConstantFlow } double flow_rate; MathLib::PiecewiseLinearInterpolation const& temperature_curve; + static constexpr bool is_power_bc = false; }; struct TemperatureCurveFlowCurve @@ -47,6 +48,7 @@ struct TemperatureCurveFlowCurve } MathLib::PiecewiseLinearInterpolation const& flow_rate_curve; MathLib::PiecewiseLinearInterpolation const& temperature_curve; + static constexpr bool is_power_bc = false; }; struct FixedPowerConstantFlow @@ -60,6 +62,7 @@ struct FixedPowerConstantFlow double power; // Value is expected to be in Watt. double heat_capacity; double density; + static constexpr bool is_power_bc = true; }; struct FixedPowerFlowCurve @@ -74,6 +77,7 @@ struct FixedPowerFlowCurve double power; // Value is expected to be in Watt. double heat_capacity; double density; + static constexpr bool is_power_bc = true; }; struct PowerCurveConstantFlow @@ -92,6 +96,7 @@ struct PowerCurveConstantFlow double flow_rate; double heat_capacity; double density; + static constexpr bool is_power_bc = true; }; struct PowerCurveFlowCurve @@ -111,6 +116,7 @@ struct PowerCurveFlowCurve double heat_capacity; double density; + static constexpr bool is_power_bc = true; }; struct BuildingPowerCurveConstantFlow @@ -134,6 +140,7 @@ struct BuildingPowerCurveConstantFlow double flow_rate; double heat_capacity; double density; + static constexpr bool is_power_bc = true; }; using FlowAndTemperatureControl = std::variant createHeatTransportBHEProcess( //! \ogs_file_param{prj__processes__process__HEAT_TRANSPORT_BHE__use_server_communication} config.getConfigParameter("use_server_communication", false); + auto const using_algebraic_bc = + //! \ogs_file_param{prj__processes__process__HEAT_TRANSPORT_BHE__use_algebraic_bc} + config.getConfigParameter("use_algebraic_bc", false); + + auto const weighting_factor = + //! \ogs_file_param{prj__processes__process__HEAT_TRANSPORT_BHE__weighting_factor} + config.getConfigParameter("weighting_factor", 100.0); + + auto const is_linear = + //! \ogs_file_param{prj__processes__process__HEAT_TRANSPORT_BHE__linear} + config.getConfigParameter("linear", false); + if (is_linear) + { + if (!using_algebraic_bc) + { + OGS_FATAL( + "You specified that the process simulated by OGS is linear. " + "For the Heat-Transport-BHE process this can only be done " + "together with setting the use_algebraic_bc option to true.") + } + else + { + WARN( + "You specified that the process simulated by OGS is linear. " + "With that optimization the process will be assembled only " + "once and the non-linear solver will do only one iteration per " + "time step. No non-linearities will be resolved and OGS will " + "not detect if there are any non-linearities. It is your " + "responsibility to ensure that the assembled equation systems " + "are linear, indeed! There is no safety net!"); + } + } + for ( auto const& bhe_config : //! \ogs_file_param{prj__processes__process__HEAT_TRANSPORT_BHE__borehole_heat_exchangers__borehole_heat_exchanger} @@ -218,7 +251,8 @@ std::unique_ptr createHeatTransportBHEProcess( HeatTransportBHEProcessData process_data( std::move(media_map), std::move(bhes), py_object, using_tespy, - using_server_communication); + using_server_communication, + {using_algebraic_bc, weighting_factor, is_linear}); SecondaryVariableCollection secondary_variables; diff --git a/ProcessLib/HeatTransportBHE/HeatTransportBHEProcess.cpp b/ProcessLib/HeatTransportBHE/HeatTransportBHEProcess.cpp index 5b2a54b1110..4e7add01661 100644 --- a/ProcessLib/HeatTransportBHE/HeatTransportBHEProcess.cpp +++ b/ProcessLib/HeatTransportBHE/HeatTransportBHEProcess.cpp @@ -172,6 +172,13 @@ void HeatTransportBHEProcess::assembleConcreteProcess( _global_assembler, &VectorMatrixAssembler::assemble, _local_assemblers, getActiveElementIDs(), dof_table, t, dt, x, x_prev, process_id, &M, &K, &b); + // Algebraic BC procedure. + if (_process_data._algebraic_BC_Setting._use_algebraic_bc) + { + algebraicBcConcreteProcess(t, dt, x, x_prev, process_id, M, K, b); + } + + //_global_output(t, process_id, M, K, b); } void HeatTransportBHEProcess::assembleWithJacobianConcreteProcess( @@ -340,16 +347,120 @@ void HeatTransportBHEProcess::postTimestepConcreteProcess( } } +void HeatTransportBHEProcess::algebraicBcConcreteProcess( + [[maybe_unused]] const double t, double const /*dt*/, + [[maybe_unused]] std::vector const& x, + std::vector const& /*xprev*/, int const /*process_id*/, + [[maybe_unused]] GlobalMatrix& M, [[maybe_unused]] GlobalMatrix& K, + [[maybe_unused]] GlobalVector& b) +{ +#ifndef USE_PETSC + auto M_normal = M.getRawMatrix(); + auto K_normal = K.getRawMatrix(); + auto n_original_rows = K_normal.rows(); + auto const n_BHE_bottom_pairs = _vec_bottom_BHE_node_indices.size(); + auto const n_BHE_top_pairs = _vec_top_BHE_node_indices.size(); + + // apply weighting factor based on the max value from column wise inner + // product and scale it with user defined value + const double w_val = + _process_data._algebraic_BC_Setting._weighting_factor * + (Eigen::RowVectorXd::Ones(K_normal.rows()) * K_normal.cwiseAbs()) + .maxCoeff(); + + M_normal.conservativeResize( + M_normal.rows() + n_BHE_bottom_pairs + n_BHE_top_pairs, + M_normal.cols()); + K_normal.conservativeResize( + K_normal.rows() + n_BHE_bottom_pairs + n_BHE_top_pairs, + K_normal.cols()); + + for (std::size_t i = 0; i < n_BHE_bottom_pairs; i++) + { + Eigen::SparseVector M_Plus(M_normal.cols()); + M_Plus.setZero(); + M_normal.row(n_original_rows + i) = M_Plus; + + Eigen::SparseVector K_Plus(K_normal.cols()); + K_Plus.setZero(); + + auto const [bhe_idx, first_BHE_bottom_index, second_BHE_bottom_index] = + _vec_bottom_BHE_node_indices[i]; + + K_Plus.insert(first_BHE_bottom_index) = w_val; + K_Plus.insert(second_BHE_bottom_index) = -w_val; + + K_normal.row(n_original_rows + i) = K_Plus; + } + + auto b_normal = b.getRawVector(); + Eigen::SparseVector b_Plus(b_normal.rows() + n_BHE_bottom_pairs + + n_BHE_top_pairs); + b_Plus.setZero(); + + // Copy values from the original column vector to the modified one + for (int i = 0; i < b_normal.innerSize(); ++i) + { + b_Plus.insert(i) = b_normal.coeff(i); + } + + for (std::size_t i = 0; i < n_BHE_top_pairs; i++) + { + Eigen::SparseVector M_Plus(M_normal.cols()); + M_Plus.setZero(); + M_normal.row(n_original_rows + n_BHE_bottom_pairs + i) = M_Plus; + + Eigen::SparseVector K_Plus(K_normal.cols()); + K_Plus.setZero(); + + auto const [bhe_idx, first_BHE_top_index, second_BHE_top_index] = + _vec_top_BHE_node_indices[i]; + + auto first_BHE_top_index_pair = first_BHE_top_index; + auto second_BHE_top_index_pair = second_BHE_top_index; + + K_Plus.insert(first_BHE_top_index_pair) = + w_val; // for power BC, the inflow node must be positive + K_Plus.insert(second_BHE_top_index_pair) = + -w_val; // for power BC, the outflow node must be negative + + K_normal.row(n_original_rows + n_BHE_bottom_pairs + i) = K_Plus; + + // get the delta_T value here + double const T_out = (*x[0])[second_BHE_top_index_pair]; + + auto calculate_delta_T = [&](auto& bhe) + { + auto const T_in = bhe.updateFlowRateAndTemperature(T_out, t); + return T_in - T_out; + }; + auto delta_T = std::visit(calculate_delta_T, + _process_data._vec_BHE_property[bhe_idx]); + + b_Plus.insert(n_original_rows + n_BHE_bottom_pairs + i) = + delta_T * w_val; + } + + M.getRawMatrix() = M_normal; + K.getRawMatrix() = K_normal; + b.getRawVector() = b_Plus; +#else + OGS_FATAL( + "The Algebraic Boundary Condition is not implemented for use with " + "PETsc Library! Simulation will be terminated."); +#endif +} + void HeatTransportBHEProcess::createBHEBoundaryConditionTopBottom( std::vector> const& all_bhe_nodes) { const int process_id = 0; auto& bcs = _boundary_conditions[process_id]; - int const n_BHEs = static_cast(_process_data._vec_BHE_property.size()); + std::size_t const n_BHEs = _process_data._vec_BHE_property.size(); // for each BHE - for (int bhe_i = 0; bhe_i < n_BHEs; bhe_i++) + for (std::size_t bhe_i = 0; bhe_i < n_BHEs; bhe_i++) { auto const& bhe_nodes = all_bhe_nodes[bhe_i]; // find the variable ID @@ -434,6 +545,20 @@ void HeatTransportBHEProcess::createBHEBoundaryConditionTopBottom( nodes_and_components[1].second)); }; + auto get_global_bhe_bc_indices_with_bhe_idx = + [&](std::size_t bhe_idx, + std::array< + std::pair, 2> + nodes_and_components) + { + return std::make_tuple( + bhe_idx, + get_global_index(nodes_and_components[0].first, + nodes_and_components[0].second), + get_global_index(nodes_and_components[1].first, + nodes_and_components[1].second)); + }; + auto createBCs = [&, bc_top_node_id = bhe_boundary_nodes[0]->getID(), bc_bottom_node_id = bhe_boundary_nodes[1]->getID()](auto& bhe) @@ -442,10 +567,11 @@ void HeatTransportBHEProcess::createBHEBoundaryConditionTopBottom( bhe.inflow_outflow_bc_component_ids) { if (bhe.use_python_bcs || - _process_data._use_server_communication) + this->_process_data._use_server_communication) // call BHEPythonBoundarycondition { - if (_process_data.py_bc_object) // the bc object exist + if (this->_process_data + .py_bc_object) // the bc object exist { // apply the customized top, inflow BC. bcs.addBoundaryCondition( @@ -466,16 +592,33 @@ void HeatTransportBHEProcess::createBHEBoundaryConditionTopBottom( } else { - // Top, inflow, normal case - bcs.addBoundaryCondition( - createBHEInflowDirichletBoundaryCondition( - get_global_bhe_bc_indices( - bhe.getBHEInflowDirichletBCNodesAndComponents( - bc_top_node_id, bc_bottom_node_id, - in_out_component_id.first)), - [&bhe](double const T, double const t) { - return bhe.updateFlowRateAndTemperature(T, t); - })); + if (this->_process_data._algebraic_BC_Setting + ._use_algebraic_bc && + bhe.isPowerBC()) + { + // for algebraic_bc method, record the pair of indices + // in a separate vector + _vec_top_BHE_node_indices.push_back( + get_global_bhe_bc_indices_with_bhe_idx( + bhe_i, + {{{bc_top_node_id, in_out_component_id.first}, + {bc_top_node_id, + in_out_component_id.second}}})); + } + else + { + // Top, inflow, normal case + bcs.addBoundaryCondition( + createBHEInflowDirichletBoundaryCondition( + get_global_bhe_bc_indices( + bhe.getBHEInflowDirichletBCNodesAndComponents( + bc_top_node_id, bc_bottom_node_id, + in_out_component_id.first)), + [&bhe](double const T, double const t) { + return bhe.updateFlowRateAndTemperature(T, + t); + })); + } } auto const bottom_nodes_and_components = @@ -484,9 +627,12 @@ void HeatTransportBHEProcess::createBHEBoundaryConditionTopBottom( in_out_component_id.first, in_out_component_id.second); - if (bottom_nodes_and_components) + if (bottom_nodes_and_components && + !this->_process_data._algebraic_BC_Setting + ._use_algebraic_bc) { - // Bottom, outflow, all cases + // Bottom, outflow, all cases | not needed for algebraic_bc + // method bcs.addBoundaryCondition( createBHEBottomDirichletBoundaryCondition( get_global_bhe_bc_indices( @@ -495,6 +641,19 @@ void HeatTransportBHEProcess::createBHEBoundaryConditionTopBottom( {bc_bottom_node_id, in_out_component_id.second}}}))); } + else if (bottom_nodes_and_components && + this->_process_data._algebraic_BC_Setting + ._use_algebraic_bc) + { + // for algebraic_bc method, record the pair of indices in a + // separate vector + _vec_bottom_BHE_node_indices.push_back( + get_global_bhe_bc_indices_with_bhe_idx( + bhe_i, + {{{bc_bottom_node_id, in_out_component_id.first}, + {bc_bottom_node_id, + in_out_component_id.second}}})); + } } }; visit(createBCs, _process_data._vec_BHE_property[bhe_i]); diff --git a/ProcessLib/HeatTransportBHE/HeatTransportBHEProcess.h b/ProcessLib/HeatTransportBHE/HeatTransportBHEProcess.h index e59d3af65fc..a50d8f66e2b 100644 --- a/ProcessLib/HeatTransportBHE/HeatTransportBHEProcess.h +++ b/ProcessLib/HeatTransportBHE/HeatTransportBHEProcess.h @@ -39,7 +39,18 @@ class HeatTransportBHEProcess final : public Process //! \name ODESystem interface //! @{ - bool isLinear() const override { return false; } + bool isLinear() const override + { + return _process_data._algebraic_BC_Setting._is_linear; + } + + bool requiresNormalization() const override + { + // In the current setup, when using algebraic bc, + // then normalization is always required + return _process_data._algebraic_BC_Setting._use_algebraic_bc; + } + //! @} void computeSecondaryVariableConcrete(double const t, double const dt, std::vector const& x, @@ -76,6 +87,12 @@ class HeatTransportBHEProcess final : public Process const double t, const double dt, int const process_id) override; + void algebraicBcConcreteProcess(const double t, double const dt, + std::vector const& x, + std::vector const& xdot, + int const process_id, GlobalMatrix& M, + GlobalMatrix& K, GlobalVector& b); + NumLib::IterationResult postIterationConcreteProcess( GlobalVector const& x) override; @@ -89,6 +106,18 @@ class HeatTransportBHEProcess final : public Process std::vector> _mesh_subset_BHE_soil_nodes; + // a vector of tuple structure containing the indices of BHE top nodes, + // used only for algebraic boundary conditions + // first object is the index of BHE + // second and third object is the global indices of a pair of unknowns, + // pointing to the inflow and outflow temperature + std::vector> + _vec_top_BHE_node_indices; + // a vector of tuple structure containing the indices of BHE bottom nodes, + // used only for algebraic boundary conditions + // same structure as the top node vector + std::vector> + _vec_bottom_BHE_node_indices; std::unique_ptr _mesh_subset_soil_nodes; diff --git a/ProcessLib/HeatTransportBHE/HeatTransportBHEProcessData.h b/ProcessLib/HeatTransportBHE/HeatTransportBHEProcessData.h index 134b42c5a54..5aa319a139c 100644 --- a/ProcessLib/HeatTransportBHE/HeatTransportBHEProcessData.h +++ b/ProcessLib/HeatTransportBHE/HeatTransportBHEProcessData.h @@ -23,6 +23,15 @@ class Element; namespace ProcessLib::HeatTransportBHE { +struct AlgebraicBCSetting +{ + const bool _use_algebraic_bc; + + const double _weighting_factor; + + const bool _is_linear; +}; + struct HeatTransportBHEProcessData final { HeatTransportBHEProcessData( @@ -31,12 +40,14 @@ struct HeatTransportBHEProcessData final BHEInflowPythonBoundaryConditionPythonSideInterface* py_bc_object_ = nullptr, const bool use_tespy = false, - const bool use_server_communication = false) + const bool use_server_communication = false, + AlgebraicBCSetting algebraicBCSetting = {false, 100.0, false}) : media_map(media_map_), _vec_BHE_property(std::move(vec_BHEs_)), py_bc_object(py_bc_object_), _use_tespy(use_tespy), - _use_server_communication(use_server_communication) + _use_server_communication(use_server_communication), + _algebraic_BC_Setting(algebraicBCSetting) { } MaterialPropertyLib::MaterialSpatialDistributionMap media_map; @@ -52,5 +63,7 @@ struct HeatTransportBHEProcessData final const bool _use_tespy; const bool _use_server_communication; + + AlgebraicBCSetting const _algebraic_BC_Setting; }; } // namespace ProcessLib::HeatTransportBHE diff --git a/ProcessLib/HeatTransportBHE/LocalAssemblers/HeatTransportBHELocalAssemblerBHE-impl.h b/ProcessLib/HeatTransportBHE/LocalAssemblers/HeatTransportBHELocalAssemblerBHE-impl.h index e4fb2d485fe..f4c44748c0d 100644 --- a/ProcessLib/HeatTransportBHE/LocalAssemblers/HeatTransportBHELocalAssemblerBHE-impl.h +++ b/ProcessLib/HeatTransportBHE/LocalAssemblers/HeatTransportBHELocalAssemblerBHE-impl.h @@ -234,8 +234,8 @@ void HeatTransportBHELocalAssemblerBHE:: auto local_rhs = MathLib::createZeroedVector( local_rhs_data, local_matrix_size); - std::vector local_M_data(local_Jac_data.size()); - std::vector local_K_data(local_Jac_data.size()); + std::vector local_M_data; + std::vector local_K_data; assemble(t, dt, local_x, local_x_prev, local_M_data, local_K_data, local_rhs_data /*not going to be used*/); diff --git a/ProcessLib/HeatTransportBHE/LocalAssemblers/HeatTransportBHELocalAssemblerSoil-impl.h b/ProcessLib/HeatTransportBHE/LocalAssemblers/HeatTransportBHELocalAssemblerSoil-impl.h index fc1443e76f9..6b9b5b42e58 100644 --- a/ProcessLib/HeatTransportBHE/LocalAssemblers/HeatTransportBHELocalAssemblerSoil-impl.h +++ b/ProcessLib/HeatTransportBHE/LocalAssemblers/HeatTransportBHELocalAssemblerSoil-impl.h @@ -211,8 +211,8 @@ void HeatTransportBHELocalAssemblerSoil::assembleWithJacobian( auto local_rhs = MathLib::createZeroedVector( local_rhs_data, local_matrix_size); - std::vector local_M_data(local_Jac_data.size()); - std::vector local_K_data(local_Jac_data.size()); + std::vector local_M_data; + std::vector local_K_data; assemble(t, dt, local_x, local_x_prev, local_M_data, local_K_data, local_rhs_data /*not going to be used*/); diff --git a/ProcessLib/HeatTransportBHE/Tests.cmake b/ProcessLib/HeatTransportBHE/Tests.cmake index 7334aa699df..19f4fc36d7b 100644 --- a/ProcessLib/HeatTransportBHE/Tests.cmake +++ b/ProcessLib/HeatTransportBHE/Tests.cmake @@ -1,3 +1,73 @@ +AddTest( + NAME HeatTransportBHE_1U_3D_bhe_sandwich + PATH Parabolic/T/3D_BHE_Sandwich + EXECUTABLE ogs + EXECUTABLE_ARGS sandwich.prj + WRAPPER time + TESTER vtkdiff + REQUIREMENTS NOT OGS_USE_MPI + RUNTIME 10 + DIFF_DATA + sandwich_ts_10_t_600.000000.vtu sandwich_ts_10_t_600.000000.vtu temperature_BHE1 temperature_BHE1 0 5e-15 + sandwich_ts_10_t_600.000000.vtu sandwich_ts_10_t_600.000000.vtu temperature_soil temperature_soil 0 1e-13 +) + +AddTest( + NAME HeatTransportBHE_1U_3D_bhe_sandwich_Newton + PATH Parabolic/T/3D_BHE_Sandwich + EXECUTABLE ogs + EXECUTABLE_ARGS sandwich_newton.xml + WRAPPER time + TESTER vtkdiff + REQUIREMENTS NOT OGS_USE_MPI + RUNTIME 10 + DIFF_DATA + sandwich_ts_10_t_600.000000.vtu sandwich_newton_ts_10_t_600.000000.vtu temperature_BHE1 temperature_BHE1 0 1e-14 + sandwich_ts_10_t_600.000000.vtu sandwich_newton_ts_10_t_600.000000.vtu temperature_soil temperature_soil 0 1e-13 +) + +AddTest( + NAME HeatTransportBHE_1U_3D_bhe_sandwich_algebraicBC + PATH Parabolic/T/3D_BHE_Sandwich + EXECUTABLE ogs + EXECUTABLE_ARGS sandwich_algebraicBC.xml + WRAPPER time + TESTER vtkdiff + REQUIREMENTS NOT OGS_USE_MPI + RUNTIME 20 + DIFF_DATA + sandwich_ts_10_t_600.000000.vtu sandwich_algebraic_bc_ts_10_t_600.000000.vtu temperature_BHE1 temperature_BHE1 0 1e-6 + sandwich_ts_10_t_600.000000.vtu sandwich_algebraic_bc_ts_10_t_600.000000.vtu temperature_soil temperature_soil 0 5e-9 +) + +AddTest( + NAME HeatTransportBHE_1U_3D_bhe_sandwich_fixed_power + PATH Parabolic/T/3D_BHE_Sandwich + RUNTIME 100 + EXECUTABLE ogs + EXECUTABLE_ARGS sandwich_fixed_power.prj + WRAPPER time + TESTER vtkdiff + REQUIREMENTS NOT OGS_USE_MPI + DIFF_DATA + sandwich_fixed_power_ts_10_t_600.000000.vtu sandwich_fixed_power_ts_10_t_600.000000.vtu temperature_BHE1 temperature_BHE1 0 5e-15 + sandwich_fixed_power_ts_10_t_600.000000.vtu sandwich_fixed_power_ts_10_t_600.000000.vtu temperature_soil temperature_soil 0 1e-13 +) + +AddTest( + NAME HeatTransportBHE_1U_3D_bhe_sandwich_fixed_power_algebraicBC + PATH Parabolic/T/3D_BHE_Sandwich + RUNTIME 100 + EXECUTABLE ogs + EXECUTABLE_ARGS sandwich_fixed_power_algebraicBC.xml + WRAPPER time + TESTER vtkdiff + REQUIREMENTS NOT OGS_USE_MPI + DIFF_DATA + sandwich_fixed_power_ts_10_t_600.000000.vtu sandwich_fixed_power_algebraic_bc_ts_10_t_600.000000.vtu temperature_BHE1 temperature_BHE1 0 5e-3 + sandwich_fixed_power_ts_10_t_600.000000.vtu sandwich_fixed_power_algebraic_bc_ts_10_t_600.000000.vtu temperature_soil temperature_soil 0 1e-6 +) + AddTest( NAME HeatTransportBHE_1U_3D_beier_sandbox PATH Parabolic/T/3D_Beier_sandbox @@ -26,6 +96,20 @@ AddTest( beier_sandbox_ts_10_t_600.000000.vtu beier_sandbox_newton_ts_10_t_600.000000.vtu temperature_soil temperature_soil 0 1e-13 ) +AddTest( + NAME HeatTransportBHE_1U_3D_beier_sandbox_algebraicBC + PATH Parabolic/T/3D_Beier_sandbox + EXECUTABLE ogs + EXECUTABLE_ARGS beier_sandbox_algebraicBC.xml + WRAPPER time + TESTER vtkdiff + REQUIREMENTS NOT OGS_USE_MPI + RUNTIME 20 + DIFF_DATA + beier_sandbox_ts_10_t_600.000000.vtu beier_sandbox_algebraic_bc_ts_10_t_600.000000.vtu temperature_BHE1 temperature_BHE1 0 5e-7 + beier_sandbox_ts_10_t_600.000000.vtu beier_sandbox_algebraic_bc_ts_10_t_600.000000.vtu temperature_soil temperature_soil 0 5e-10 +) + AddTest( NAME HeatTransportBHE_1U_beier_sandbox_fixed_power_constant_flow PATH Parabolic/T/3D_Beier_sandbox @@ -40,6 +124,20 @@ AddTest( fixed_power_constant_flow_ts_10_t_600.000000.vtu fixed_power_constant_flow_ts_10_t_600.000000.vtu temperature_soil temperature_soil 0 1e-13 ) +AddTest( + NAME HeatTransportBHE_1U_beier_sandbox_fixed_power_constant_flow_algebraicBC + PATH Parabolic/T/3D_Beier_sandbox + RUNTIME 220 + EXECUTABLE ogs + EXECUTABLE_ARGS fixed_power_constant_flow_algebraicBC.xml + WRAPPER time + TESTER vtkdiff + REQUIREMENTS NOT OGS_USE_MPI + DIFF_DATA + fixed_power_constant_flow_ts_10_t_600.000000.vtu fixed_power_constant_flow_algebraic_bc_ts_10_t_600.000000.vtu temperature_BHE1 temperature_BHE1 0 1e-4 + fixed_power_constant_flow_ts_10_t_600.000000.vtu fixed_power_constant_flow_algebraic_bc_ts_10_t_600.000000.vtu temperature_soil temperature_soil 0 5e-9 +) + AddTest( NAME HeatTransportBHE_coaxial_pipe_3D_deep_BHE_CXA PATH Parabolic/T/3D_deep_BHE @@ -85,7 +183,7 @@ AddTest( AddTest( NAME HeatTransportBHE_3D_BHE_groundwater_advection PATH Parabolic/T/3D_BHE_GW_advection - RUNTIME 8 + RUNTIME 4 EXECUTABLE ogs EXECUTABLE_ARGS BHE_GW_advection.prj WRAPPER time @@ -176,5 +274,5 @@ AddTest( ) if(NOT OGS_USE_PETSC) - NotebookTest(NOTEBOOKFILE Parabolic/T/BHE_1P/pipe_flow_ebhe.md RUNTIME 600) + NotebookTest(NOTEBOOKFILE Parabolic/T/BHE_1P/pipe_flow_ebhe.md RUNTIME 200) endif() diff --git a/ProcessLib/Process.h b/ProcessLib/Process.h index 3b2f076105d..b8c4fd9ed64 100644 --- a/ProcessLib/Process.h +++ b/ProcessLib/Process.h @@ -192,6 +192,8 @@ class Process { } + bool requiresNormalization() const override { return false; } + protected: std::vector getDOFTables( int const number_of_processes) const; diff --git a/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich.prj b/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich.prj new file mode 100644 index 00000000000..d07938d11ae --- /dev/null +++ b/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich.prj @@ -0,0 +1,242 @@ + + + + sandwich.vtu + + + + HeatTransportBHE + HEAT_TRANSPORT_BHE + 2 + + temperature_soil + temperature_BHE1 + + + + 1U + + TemperatureCurveConstantFlow + 1e-3 + fluid_temperature + + + 3.0 + 0.2 + + + 2190.0 + 0.0 + 1781 + 1.4 + + + + 0.02 + 0.003 + 0.43 + + + 0.02 + 0.003 + 0.43 + + 0.075 + 0.001 + + + 1000 + 0.005 + 4000 + 0.5 + 293.15 + + + + + + + + + + AqueousLiquid + + + phase_velocity + Constant + 0 0 0 + + + specific_heat_capacity + Constant + 3795 + + + density + Constant + 1000 + + + + + Solid + + + specific_heat_capacity + Constant + 2000 + + + density + Constant + 1000 + + + + + Gas + + + specific_heat_capacity + Constant + 1000 + + + density + Constant + 2500 + + + + + + + porosity + Constant + 0 + + + thermal_conductivity + Constant + 2.0 + + + thermal_longitudinal_dispersivity + Constant + 5 + + + thermal_transversal_dispersivity + Constant + 0.5 + + + + + + + + basic_picard + + DeltaX + NORM2 + 1.e-10 + + BackwardEuler + + FixedTimeStepping + 0.0 + 600 + + + 1 + 60 + + + + + + + VTK + sandwich + + + 1 + 1 + + + + temperature_soil + temperature_BHE1 + + + + + + T0 + Constant + 293.15 + + + T_soil_imposed + Constant + 273.15 + + + T0_BHE + Constant + 293.15 293.15 293.15 293.15 + + + + + temperature_soil + 1 + 1 + T0 + + + + + temperature_BHE1 + 4 + 1 + T0_BHE + + + + + basic_picard + Picard + 100 + general_linear_solver + + + + + general_linear_solver + -i cg -p jacobi -tol 1e-16 -maxiter 10000 + + BiCGSTAB + ILUT + 1000 + 1e-16 + + + gw + -gw_ksp_type cg -gw_pc_type bjacobi -gw_ksp_rtol 1e-16 -gw_ksp_max_it 10000 + + + + + + fluid_temperature + + 0 864000 + + + 273.15 273.15 + + + + diff --git a/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich.vtu b/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich.vtu new file mode 100644 index 00000000000..8939db6e61d --- /dev/null +++ b/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich.vtu @@ -0,0 +1,38 @@ + + + + + + + + + 0 0 0 1 1 1 + + + + + 0 0 0 0 1 0 + 1 0 0 0 0 1 + 0 1 1 1 0 1 + 0 0 2 0 1 2 + 1 0 2 0 0 3 + 0 1 3 1 0 3 + + + + + 0 1 2 3 4 5 + 3 4 5 6 7 8 + 6 7 8 9 10 11 + 9 6 6 3 3 0 + + + 6 12 18 20 22 24 + + + 13 13 13 3 3 3 + + + + + diff --git a/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich_algebraicBC.xml b/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich_algebraicBC.xml new file mode 100644 index 00000000000..5df447f6532 --- /dev/null +++ b/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich_algebraicBC.xml @@ -0,0 +1,15 @@ + + + + true + + + 100 + + + true + + sandwich_algebraic_bc + CG + DIAGONAL + diff --git a/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich_fixed_power.prj b/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich_fixed_power.prj new file mode 100644 index 00000000000..99a3fc2be90 --- /dev/null +++ b/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich_fixed_power.prj @@ -0,0 +1,231 @@ + + + + sandwich.vtu + + + + HeatTransportBHE + HEAT_TRANSPORT_BHE + 2 + + temperature_soil + temperature_BHE1 + + + + 1U + + FixedPowerConstantFlow + 1e-3 + 10 + + + 3.0 + 0.2 + + + 2190.0 + 0.0 + 1781 + 1.4 + + + + 0.02 + 0.003 + 0.43 + + + 0.02 + 0.003 + 0.43 + + 0.075 + 0.001 + + + 1000 + 0.005 + 4000 + 0.5 + 293.15 + + + + + + + + + + AqueousLiquid + + + phase_velocity + Constant + 0 0 0 + + + specific_heat_capacity + Constant + 3795 + + + density + Constant + 1000 + + + + + Solid + + + specific_heat_capacity + Constant + 2000 + + + density + Constant + 1000 + + + + + Gas + + + specific_heat_capacity + Constant + 1000 + + + density + Constant + 2500 + + + + + + + porosity + Constant + 0 + + + thermal_conductivity + Constant + 2.0 + + + thermal_longitudinal_dispersivity + Constant + 5 + + + thermal_transversal_dispersivity + Constant + 0.5 + + + + + + + + basic_picard + + DeltaX + NORM2 + 1.e-6 + + BackwardEuler + + FixedTimeStepping + 0.0 + 600 + + + 10 + 60 + + + + + + + VTK + sandwich_fixed_power + + + 1 + 1 + + + + temperature_soil + temperature_BHE1 + + + + + + T0 + Constant + 293.15 + + + T_soil_imposed + Constant + 273.15 + + + T0_BHE + Constant + 293.15 293.15 293.15 293.15 + + + + + temperature_soil + 1 + 1 + T0 + + + + + temperature_BHE1 + 4 + 1 + T0_BHE + + + + + basic_picard + Picard + 100 + general_linear_solver + + + + + general_linear_solver + -i cg -p jacobi -tol 1e-16 -maxiter 10000 + + BiCGSTAB + ILUT + 1000 + 1e-16 + + + gw + -gw_ksp_type cg -gw_pc_type bjacobi -gw_ksp_rtol 1e-16 -gw_ksp_max_it 10000 + + + + diff --git a/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich_fixed_power_algebraicBC.xml b/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich_fixed_power_algebraicBC.xml new file mode 100644 index 00000000000..a39dedc70ac --- /dev/null +++ b/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich_fixed_power_algebraicBC.xml @@ -0,0 +1,15 @@ + + + + true + + + 100 + + + true + + sandwich_fixed_power_algebraic_bc + CG + DIAGONAL + diff --git a/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich_fixed_power_ts_10_t_600.000000.vtu b/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich_fixed_power_ts_10_t_600.000000.vtu new file mode 100644 index 00000000000..58c13e2dc7c --- /dev/null +++ b/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich_fixed_power_ts_10_t_600.000000.vtu @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + _AQAAAAAAAAAAgAAAAAAAAAUAAAAAAAAADQAAAAAAAAA=eF4z0zPVMwIAAvgA+g==AQAAAAAAAAAAgAAAAAAAAIABAAAAAAAAfAAAAAAAAAA=eF6bIJF7e0ZokUPxa/nF04C0/+rfT2uCihxcKlZfBtEMFIL1zf+vzASa634pe9VUIK302PI9yNzzqytOUcP85ugn52cBzW3682TDFCD9KLbjB9hcW9uD1DDfuPLrydlAc0/nrNsxGUjvVDzHWAs09+UHwR3UMB8Aj3g/IQ==AQAAAAAAAAAAgAAAAAAAAGAAAAAAAAAAOwAAAAAAAAA=eF5Li1ngkB5U5HD//3PZNCD9DEp/WAsRv/cEwr8IpZutFoLFNbZB+EZQOo9hEVi8oQTCr4XSAJ2dKw8=AQAAAAAAAAAAgAAAAAAAACABAAAAAAAAMQAAAAAAAAA=eF5jYCAGfLDHz8cFcOlDp3GphwMHVC5cnQMaHwYcGLACDjRxmD6YOLo5HA4ArTYOng==AQAAAAAAAAAAgAAAAAAAAMAAAAAAAAAAMAAAAAAAAAA=eF5jYIAARijNBKWZoTQLlGYlIM4GpdmhNAcBcU4ozQWludHE2dBoZjQaBgAsKAB/AQAAAAAAAAAAgAAAAAAAADAAAAAAAAAAGAAAAAAAAAA=eF5jY4AAHigtBKVFoLQYlJaA0gAJcABnAQAAAAAAAAAAgAAAAAAAAAYAAAAAAAAADgAAAAAAAAA=eF7j5eVlZmYGAADbADE= + + diff --git a/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich_newton.xml b/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich_newton.xml new file mode 100644 index 00000000000..073327ee73b --- /dev/null +++ b/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich_newton.xml @@ -0,0 +1,9 @@ + + + newton_nonlinear_solver + Residual + sandwich_newton + newton_nonlinear_solver + Newton + 10 + diff --git a/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich_ts_10_t_600.000000.vtu b/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich_ts_10_t_600.000000.vtu new file mode 100644 index 00000000000..cbe4bc0f70b --- /dev/null +++ b/Tests/Data/Parabolic/T/3D_BHE_Sandwich/sandwich_ts_10_t_600.000000.vtu @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + _AQAAAAAAAAAAgAAAAAAAAAUAAAAAAAAADQAAAAAAAAA=eF4z0zPVMwIAAvgA+g==AQAAAAAAAAAAgAAAAAAAAIABAAAAAAAAfAAAAAAAAAA=eF47P8/gU6hwocN5KO1zw/+ghFuRw2GPokMgmoFC8KCyx5MNaG5NpmrHUiBtL3+6WARo7jKfIj5ZKphfYvrGdJtQoYOvFHPSV6D53//tlBMAmisify1OkQrmp4EA0PyyfwYXXUQKHVj8hc5xA82duWjrclUqmA8AKOsxSw==AQAAAAAAAAAAgAAAAAAAAGAAAAAAAAAAQQAAAAAAAAA=eF5b583RfzWwyGH6e9a6aUFFDj1QmkfxZx9IPO8bF5hfAKX3V58Ci5vmSIH5elBaXqQWLP5S2ATMvw6lAf4DKNs=AQAAAAAAAAAAgAAAAAAAACABAAAAAAAAMQAAAAAAAAA=eF5jYCAGfLDHz8cFcOlDp3GphwMHVC5cnQMaHwYcGLACDjRxmD6YOLo5HA4ArTYOng==AQAAAAAAAAAAgAAAAAAAAMAAAAAAAAAAMAAAAAAAAAA=eF5jYIAARijNBKWZoTQLlGYlIM4GpdmhNAcBcU4ozQWludHE2dBoZjQaBgAsKAB/AQAAAAAAAAAAgAAAAAAAADAAAAAAAAAAGAAAAAAAAAA=eF5jY4AAHigtBKVFoLQYlJaA0gAJcABnAQAAAAAAAAAAgAAAAAAAAAYAAAAAAAAADgAAAAAAAAA=eF7j5eVlZmYGAADbADE= + + diff --git a/Tests/Data/Parabolic/T/3D_Beier_sandbox/beier_sandbox_algebraicBC.xml b/Tests/Data/Parabolic/T/3D_Beier_sandbox/beier_sandbox_algebraicBC.xml new file mode 100644 index 00000000000..b0ee68e555c --- /dev/null +++ b/Tests/Data/Parabolic/T/3D_Beier_sandbox/beier_sandbox_algebraicBC.xml @@ -0,0 +1,15 @@ + + + + true + + + 100 + + + true + + beier_sandbox_algebraic_bc + CG + DIAGONAL + diff --git a/Tests/Data/Parabolic/T/3D_Beier_sandbox/fixed_power_constant_flow_algebraicBC.xml b/Tests/Data/Parabolic/T/3D_Beier_sandbox/fixed_power_constant_flow_algebraicBC.xml new file mode 100644 index 00000000000..963f9fa17a1 --- /dev/null +++ b/Tests/Data/Parabolic/T/3D_Beier_sandbox/fixed_power_constant_flow_algebraicBC.xml @@ -0,0 +1,15 @@ + + + + true + + + 100 + + + true + + fixed_power_constant_flow_algebraic_bc + CG + DIAGONAL + diff --git a/Tests/NumLib/ODEs.h b/Tests/NumLib/ODEs.h index 98d7d61b869..2f3d2e66234 100644 --- a/Tests/NumLib/ODEs.h +++ b/Tests/NumLib/ODEs.h @@ -115,6 +115,8 @@ class ODE1 final : public NumLib::ODESystem< return true; } + bool requiresNormalization() const override { return false; } + std::size_t const N = 2; }; @@ -205,6 +207,8 @@ class ODE2 final : public NumLib::ODESystem< return false; } + bool requiresNormalization() const override { return false; } + std::size_t const N = 1; }; @@ -333,6 +337,8 @@ class ODE3 final : public NumLib::ODESystem< return false; } + bool requiresNormalization() const override { return false; } + std::size_t const N = 2; };