std::unique_ptr<FluidProperties> createFluidProperties( BaseLib::ConfigTree const& config) { //! \ogs_file_param{material__fluid__density} auto const& rho_conf = config.getConfigSubtree("density"); auto liquid_density = MaterialLib::Fluid::createFluidDensityModel(rho_conf); //! \ogs_file_param{material__fluid__viscosity} auto const& mu_conf = config.getConfigSubtree("viscosity"); auto viscosity = MaterialLib::Fluid::createViscosityModel(mu_conf); const bool is_mu_density_dependent = (viscosity->getName().find("density dependent") != std::string::npos); bool is_cp_density_dependent = false; std::unique_ptr<MaterialLib::Fluid::FluidProperty> specific_heat_capacity = nullptr; auto heat_capacity__opt_conf = //! \ogs_file_param{material__fluid__specific_heat_capacity} config.getConfigSubtreeOptional("specific_heat_capacity"); if (heat_capacity__opt_conf) { const auto& heat_capacity_conf = *heat_capacity__opt_conf; specific_heat_capacity = createSpecificFluidHeatCapacityModel(heat_capacity_conf); is_cp_density_dependent = (specific_heat_capacity->getName().find("density dependent") != std::string::npos); } bool is_KT_density_dependent = false; std::unique_ptr<MaterialLib::Fluid::FluidProperty> thermal_conductivity = nullptr; auto const& thermal_conductivity_opt_conf = //! \ogs_file_param{material__fluid__thermal_conductivity} config.getConfigSubtreeOptional("thermal_conductivity"); if (thermal_conductivity_opt_conf) { auto const& thermal_conductivity_conf = *thermal_conductivity_opt_conf; thermal_conductivity = MaterialLib::Fluid::createFluidThermalConductivityModel( thermal_conductivity_conf); is_KT_density_dependent = (specific_heat_capacity->getName().find("density dependent") != std::string::npos); } if (is_mu_density_dependent || is_cp_density_dependent || is_KT_density_dependent) return std::make_unique< MaterialLib::Fluid::FluidPropertiesWithDensityDependentModels>( std::move(liquid_density), std::move(viscosity), std::move(specific_heat_capacity), std::move(thermal_conductivity), is_mu_density_dependent, is_cp_density_dependent, is_KT_density_dependent); return std::make_unique< MaterialLib::Fluid::PrimaryVariableDependentFluidProperties>( std::move(liquid_density), std::move(viscosity), std::move(specific_heat_capacity), std::move(thermal_conductivity)); }
std::unique_ptr<PythonBoundaryCondition> createPythonBoundaryCondition( BaseLib::ConfigTree const& config, MeshLib::Mesh const& boundary_mesh, NumLib::LocalToGlobalIndexMap const& dof_table, std::size_t bulk_mesh_id, int const variable_id, int const component_id, unsigned const integration_order, unsigned const shapefunction_order, unsigned const global_dim) { //! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__type} config.checkConfigParameter("type", "Python"); //! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__Python__bc_object} auto const bc_object = config.getConfigParameter<std::string>("bc_object"); //! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__Python__flush_stdout} auto const flush_stdout = config.getConfigParameter("flush_stdout", false); // Evaluate Python code in scope of main module pybind11::object scope = pybind11::module::import("__main__").attr("__dict__"); if (!scope.contains(bc_object)) OGS_FATAL( "Function `%s' is not defined in the python script file, or there " "was no python script file specified.", bc_object.c_str()); auto* bc = scope[bc_object.c_str()] .cast<PythonBoundaryConditionPythonSideInterface*>(); if (variable_id >= static_cast<int>(dof_table.getNumberOfVariables()) || component_id >= dof_table.getNumberOfVariableComponents(variable_id)) { OGS_FATAL( "Variable id or component id too high. Actual values: (%d, %d), " "maximum values: (%d, %d).", variable_id, component_id, dof_table.getNumberOfVariables(), dof_table.getNumberOfVariableComponents(variable_id)); } // In case of partitioned mesh the boundary could be empty, i.e. there is no // boundary condition. #ifdef USE_PETSC // This can be extracted to createBoundaryCondition() but then the config // parameters are not read and will cause an error. // TODO (naumov): Add a function to ConfigTree for skipping the tags of the // subtree and move the code up in createBoundaryCondition(). if (boundary_mesh.getDimension() == 0 && boundary_mesh.getNumberOfNodes() == 0 && boundary_mesh.getNumberOfElements() == 0) { return nullptr; } #endif // USE_PETSC return std::make_unique<PythonBoundaryCondition>( PythonBoundaryConditionData{ bc, dof_table, bulk_mesh_id, dof_table.getGlobalComponent(variable_id, component_id), boundary_mesh}, integration_order, shapefunction_order, global_dim, flush_stdout); }
std::unique_ptr<Process> createGroundwaterFlowProcess( MeshLib::Mesh& mesh, Process::NonlinearSolver& nonlinear_solver, std::unique_ptr<Process::TimeDiscretization>&& time_discretization, std::vector<ProcessVariable> const& variables, std::vector<std::unique_ptr<ParameterBase>> const& parameters, BaseLib::ConfigTree const& config) { //! \ogs_file_param{process__type} config.checkConfigParameter("type", "GROUNDWATER_FLOW"); DBUG("Create GroundwaterFlowProcess."); // Process variable. auto process_variables = findProcessVariables( variables, config, {//! \ogs_file_param_special{process__GROUNDWATER_FLOW__process_variables__process_variable} "process_variable"}); // Hydraulic conductivity parameter. auto& hydraulic_conductivity = findParameter<double, MeshLib::Element const&>( config, //! \ogs_file_param_special{process__GROUNDWATER_FLOW__hydraulic_conductivity} "hydraulic_conductivity", parameters); DBUG("Use \'%s\' as hydraulic conductivity parameter.", hydraulic_conductivity.name.c_str()); GroundwaterFlowProcessData process_data{hydraulic_conductivity}; SecondaryVariableCollection secondary_variables{ //! \ogs_file_param{process__secondary_variables} config.getConfigSubtreeOptional("secondary_variables"), {//! \ogs_file_param_special{process__GROUNDWATER_FLOW__secondary_variables__darcy_velocity_x} "darcy_velocity_x", //! \ogs_file_param_special{process__GROUNDWATER_FLOW__secondary_variables__darcy_velocity_y} "darcy_velocity_y", //! \ogs_file_param_special{process__GROUNDWATER_FLOW__secondary_variables__darcy_velocity_z} "darcy_velocity_z"}}; ProcessOutput //! \ogs_file_param{process__output} process_output{config.getConfigSubtree("output"), process_variables, secondary_variables}; return std::unique_ptr<Process>{new GroundwaterFlowProcess{ mesh, nonlinear_solver, std::move(time_discretization), std::move(process_variables), std::move(process_data), std::move(secondary_variables), std::move(process_output)}}; }
void Initialize(BaseLib::ConfigTree const& scripts_config, std::string const& path) { if (Processor == nullptr) { Processor = vtkCPProcessor::New(); Processor->Initialize(); } else { Processor->RemoveAllPipelines(); } //! \ogs_file_param{prj__insitu__scripts__script} for (auto script_config : scripts_config.getConfigSubtreeList("script")) { //! \ogs_file_param{prj__insitu__scripts__script__name} auto scriptName = script_config.getConfigParameter<std::string>("name"); INFO("Initializing in-situ script: %s", scriptName.c_str()); std::stringstream ss; ss << path << scriptName; vtkNew<vtkCPPythonScriptPipeline> pipeline; pipeline->Initialize(ss.str().c_str()); Processor->AddPipeline(pipeline.GetPointer()); } }
std::unique_ptr<ConvergenceCriterionPerComponentDeltaX> createConvergenceCriterionPerComponentDeltaX(const BaseLib::ConfigTree& config) { //! \ogs_file_param{prj__time_loop__processes__process__convergence_criterion__type} config.checkConfigParameter("type", "PerComponentDeltaX"); auto abstols = //! \ogs_file_param{prj__time_loop__processes__process__convergence_criterion__PerComponentDeltaX__abstols} config.getConfigParameterOptional<std::vector<double>>("abstols"); auto reltols = //! \ogs_file_param{prj__time_loop__processes__process__convergence_criterion__PerComponentDeltaX__reltols} config.getConfigParameterOptional<std::vector<double>>("reltols"); auto const norm_type_str = //! \ogs_file_param{prj__time_loop__processes__process__convergence_criterion__PerComponentDeltaX__norm_type} config.getConfigParameter<std::string>("norm_type"); if ((!abstols) && (!reltols)) OGS_FATAL( "At least one of absolute or relative tolerance has to be " "specified."); if (!abstols) { abstols = std::vector<double>(reltols->size()); } else if (!reltols) { reltols = std::vector<double>(abstols->size()); } auto const norm_type = MathLib::convertStringToVecNormType(norm_type_str); if (norm_type == MathLib::VecNormType::INVALID) OGS_FATAL("Unknown vector norm type `%s'.", norm_type_str.c_str()); return std::unique_ptr<ConvergenceCriterionPerComponentDeltaX>( new ConvergenceCriterionPerComponentDeltaX( std::move(*abstols), std::move(*reltols), norm_type)); }
std::unique_ptr<ParameterBase> createMeshElementParameter( BaseLib::ConfigTree const& config, MeshLib::Mesh const& mesh) { //! \ogs_file_param{parameter__type} config.checkConfigParameter("type", "MeshElement"); //! \ogs_file_param{parameter__MeshElement__field_name} auto const field_name = config.getConfigParameter<std::string>("field_name"); DBUG("Using field_name %s", field_name.c_str()); if (!mesh.getProperties().hasPropertyVector(field_name)) { OGS_FATAL("The required property %s does not exists in the mesh.", field_name.c_str()); } // TODO other data types than only double auto const& property = mesh.getProperties().getPropertyVector<double>(field_name); if (!property) { OGS_FATAL("The mesh property `%s' is not of the requested type.", field_name.c_str()); } if (property->getMeshItemType() != MeshLib::MeshItemType::Cell) { OGS_FATAL("The mesh property `%s' is not an element property.", field_name.c_str()); } return std::unique_ptr<ParameterBase>( new MeshElementParameter<double>(*property)); }
/** \param config ConfigTree object which contains the input data including `<type>NonWettingPhaseBrooksCoreyOilGas</type>` and it has a tag of `<relative_permeability>` */ std::unique_ptr<RelativePermeability> createNonWettingPhaseBrooksCoreyOilGas( BaseLib::ConfigTree const& config) { //! \ogs_file_param{material__porous_medium__relative_permeability__type} config.checkConfigParameter("type", "NonWettingPhaseBrooksCoreyOilGas"); //! \ogs_file_param{material__porous_medium__relative_permeability__NonWettingPhaseBrooksCoreyOilGas__sr} const auto Sr = config.getConfigParameter<double>("sr"); //! \ogs_file_param{material__porous_medium__relative_permeability__NonWettingPhaseBrooksCoreyOilGas__smax} const auto Smax = config.getConfigParameter<double>("smax"); //! \ogs_file_param{material__porous_medium__relative_permeability__NonWettingPhaseBrooksCoreyOilGas__m} const auto m = config.getConfigParameter<double>("m"); if (m < 1.0) // m >= 1 { OGS_FATAL( "The exponent parameter of NonWettingPhaseBrooksCoreyOilGas\n" "relative permeability model, m, must not be smaller than 1"); } //! \ogs_file_param{material__porous_medium__relative_permeability__NonWettingPhaseBrooksCoreyOilGas__krel_min} const auto krel_min = config.getConfigParameter<double>("krel_min"); return std::make_unique<NonWettingPhaseBrooksCoreyOilGas>( Sr, Smax, m, krel_min); }
std::unique_ptr<TimeStepAlgorithm> createTimeStepper( BaseLib::ConfigTree const& config) { //! \ogs_file_param{prj__time_loop__processes__process__time_stepping__type} auto const type = config.peekConfigParameter<std::string>("type"); std::unique_ptr<NumLib::TimeStepAlgorithm> timestepper; if (type == "SingleStep") { //! \ogs_file_param_special{prj__time_loop__processes__process__time_stepping__SingleStep} config.ignoreConfigParameter("type"); timestepper = std::make_unique<NumLib::FixedTimeStepping>(0.0, 1.0, 1.0); } else if (type == "FixedTimeStepping") { timestepper = NumLib::createFixedTimeStepping(config); } else if (type == "EvolutionaryPIDcontroller") { timestepper = NumLib::createEvolutionaryPIDcontroller(config); } else { OGS_FATAL( "Unknown time stepping type: `%s'. " "The available types are \n\tSingleStep, \n\tFixedTimeStepping" "\n\tEvolutionaryPIDcontroller\n", type.data()); } return timestepper; }
std::unique_ptr<RobinBoundaryCondition> createRobinBoundaryCondition( BaseLib::ConfigTree const& config, std::vector<MeshLib::Element*>&& elements, NumLib::LocalToGlobalIndexMap const& dof_table, int const variable_id, int const component_id, bool is_axially_symmetric, unsigned const integration_order, unsigned const global_dim, std::vector<std::unique_ptr<ParameterBase>> const& parameters) { DBUG("Constructing RobinBcConfig from config."); //! \ogs_file_param{boundary_condition__type} config.checkConfigParameter("type", "Robin"); //! \ogs_file_param{boundary_condition__Robin__alpha} auto const alpha_name = config.getConfigParameter<std::string>("alpha"); //! \ogs_file_param{boundary_condition__Robin__u_0} auto const u_0_name = config.getConfigParameter<std::string>("u_0"); auto const& alpha = findParameter<double>(alpha_name, parameters, 1); auto const& u_0 = findParameter<double>(u_0_name, parameters, 1); return std::unique_ptr<RobinBoundaryCondition>(new RobinBoundaryCondition( is_axially_symmetric, integration_order, dof_table, variable_id, component_id, global_dim, std::move(elements), RobinBoundaryConditionData{alpha, u_0})); }
/** \param config ConfigTree object which contains the input data including `<type>NonWettingPhaseVanGenuchten</type>` and it has a tag of `<relative_permeability>` */ std::unique_ptr<RelativePermeability> createNonWettingPhaseVanGenuchten( BaseLib::ConfigTree const& config) { //! \ogs_file_param{material__porous_medium__relative_permeability__type} config.checkConfigParameter("type", "NonWettingPhaseVanGenuchten"); //! \ogs_file_param{material__porous_medium__relative_permeability__NonWettingPhaseVanGenuchten__sr} const auto Sr = config.getConfigParameter<double>("sr"); //! \ogs_file_param{material__porous_medium__relative_permeability__NonWettingPhaseVanGenuchten__smax} const auto Smax = config.getConfigParameter<double>("smax"); //! \ogs_file_param{material__porous_medium__relative_permeability__NonWettingPhaseVanGenuchten__m} const auto m = config.getConfigParameter<double>("m"); if (m < 0. || m > 1.0) { OGS_FATAL( "The exponent parameter of NonWettingPhaseVanGenuchten relative\n" " permeability model, m, must be in an interval of [0, 1]"); } //! \ogs_file_param{material__porous_medium__relative_permeability__NonWettingPhaseVanGenuchten__krel_min} const auto krel_min = config.getConfigParameter<double>("krel_min"); return std::make_unique<NonWettingPhaseVanGenuchten>(Sr, Smax, m, krel_min); }
/** \param config ConfigTree object which contains the input data including <type>vanGenuchten</type> and it has a tag of <capillary_pressure> */ static std::unique_ptr<CapillaryPressureSaturation> createVanGenuchten( BaseLib::ConfigTree const& config) { //! \ogs_file_param{material_property__porous_medium__porous_medium__capillary_pressure__type} config.checkConfigParameter("type", "vanGenuchten"); //! \ogs_file_param{material_property__porous_medium__porous_medium__capillary_pressure__vanGenuchten__pd} const double pd = config.getConfigParameter<double>("pd"); //! \ogs_file_param{material_property__porous_medium__porous_medium__capillary_pressure__vanGenuchten__sr} const double Sr = config.getConfigParameter<double>("sr"); //! \ogs_file_param{material_property__porous_medium__porous_medium__capillary_pressure__vanGenuchten__smax} const double Smax = config.getConfigParameter<double>("smax"); //! \ogs_file_param{material_property__porous_medium__porous_medium__capillary_pressure__vanGenuchten__m} const double m = config.getConfigParameter<double>("m"); if (m > 1.0) // m <= 1 { OGS_FATAL( "The exponent parameter of van Genuchten capillary pressure " "saturation model, m, must be in an interval of [0, 1]"); } //! \ogs_file_param{material_property__porous_medium__porous_medium__capillary_pressure__vanGenuchten__pc_max} const double Pc_max = config.getConfigParameter<double>("pc_max"); return std::unique_ptr<CapillaryPressureSaturation>( new VanGenuchtenCapillaryPressureSaturation(pd, Sr, Smax, m, Pc_max)); }
std::unique_ptr<Process> createHeatConductionProcess( MeshLib::Mesh& mesh, std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler, std::vector<ProcessVariable> const& variables, std::vector<std::unique_ptr<ParameterBase>> const& parameters, unsigned const integration_order, BaseLib::ConfigTree const& config) { //! \ogs_file_param{process__type} config.checkConfigParameter("type", "HEAT_CONDUCTION"); DBUG("Create HeatConductionProcess."); // Process variable. auto process_variables = findProcessVariables( variables, config, {//! \ogs_file_param_special{process__HEAT_CONDUCTION__process_variables__process_variable} "process_variable"}); // thermal conductivity parameter. auto& thermal_conductivity = findParameter<double>( config, //! \ogs_file_param_special{process__HEAT_CONDUCTION__thermal_conductivity} "thermal_conductivity", parameters, 1); DBUG("Use \'%s\' as thermal conductivity parameter.", thermal_conductivity.name.c_str()); // heat capacity parameter. auto& heat_capacity = findParameter<double>( config, //! \ogs_file_param_special{process__HEAT_CONDUCTION__heat_capacity} "heat_capacity", parameters, 1); DBUG("Use \'%s\' as heat capacity parameter.", heat_capacity.name.c_str()); // density parameter. auto& density = findParameter<double>( config, //! \ogs_file_param_special{process__HEAT_CONDUCTION__density} "density", parameters, 1); DBUG("Use \'%s\' as density parameter.", density.name.c_str()); HeatConductionProcessData process_data{thermal_conductivity, heat_capacity, density}; SecondaryVariableCollection secondary_variables; NumLib::NamedFunctionCaller named_function_caller( {"HeatConduction_temperature"}); ProcessLib::parseSecondaryVariables(config, secondary_variables, named_function_caller); return std::unique_ptr<Process>{new HeatConductionProcess{ mesh, std::move(jacobian_assembler), parameters, integration_order, std::move(process_variables), std::move(process_data), std::move(secondary_variables), std::move(named_function_caller)}}; }
std::unique_ptr<ParameterBase> createCurveScaledParameter( std::string const& name, BaseLib::ConfigTree const& config, std::map<std::string, std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> const& curves) { //! \ogs_file_param{prj__parameters__parameter__type} config.checkConfigParameter("type", "CurveScaled"); //! \ogs_file_param{prj__parameters__parameter__CurveScaled__curve} auto curve_name = config.getConfigParameter<std::string>("curve"); DBUG("Using curve %s", curve_name.c_str()); auto const curve_it = curves.find(curve_name); if (curve_it == curves.end()) OGS_FATAL("Curve `%s' does not exists.", curve_name.c_str()); auto referenced_parameter_name = //! \ogs_file_param{prj__parameters__parameter__CurveScaled__parameter} config.getConfigParameter<std::string>("parameter"); DBUG("Using parameter %s", referenced_parameter_name.c_str()); // TODO other data types than only double return std::make_unique<CurveScaledParameter<double>>( name, *curve_it->second, referenced_parameter_name); }
std::unique_ptr<DirichletBoundaryCondition> createDirichletBoundaryCondition( BaseLib::ConfigTree const& config, MeshLib::Mesh const& bc_mesh, NumLib::LocalToGlobalIndexMap const& dof_table_bulk, int const variable_id, int const component_id, const std::vector<std::unique_ptr<ProcessLib::ParameterBase>>& parameters) { DBUG("Constructing DirichletBoundaryCondition from config."); //! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__type} config.checkConfigParameter("type", "Dirichlet"); //! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__Dirichlet__parameter} auto const param_name = config.getConfigParameter<std::string>("parameter"); DBUG("Using parameter %s", param_name.c_str()); auto& param = findParameter<double>(param_name, parameters, 1); // In case of partitioned mesh the boundary could be empty, i.e. there is no // boundary condition. #ifdef USE_PETSC // This can be extracted to createBoundaryCondition() but then the config // parameters are not read and will cause an error. // TODO (naumov): Add a function to ConfigTree for skipping the tags of the // subtree and move the code up in createBoundaryCondition(). if (bc_mesh.getDimension() == 0 && bc_mesh.getNumberOfNodes() == 0 && bc_mesh.getNumberOfElements() == 0) { return nullptr; } #endif // USE_PETSC return std::make_unique<DirichletBoundaryCondition>( param, bc_mesh, dof_table_bulk, variable_id, component_id); }
/** \param config ConfigTree object which contains the input data including <type>BrookCorey</type> and it has a tag of <capillary_pressure> */ static std::unique_ptr<CapillaryPressureSaturation> createBrookCorey( BaseLib::ConfigTree const& config) { //! \ogs_file_param{material_property__porous_medium__porous_medium__capillary_pressure__type} config.checkConfigParameter("type", "BrookCorey"); //! \ogs_file_param{material_property__porous_medium__porous_medium__capillary_pressure__BrookCorey__pd} const double pd = config.getConfigParameter<double>("pd"); //! \ogs_file_param{material_property__porous_medium__porous_medium__capillary_pressure__BrookCorey__sr} const double Sr = config.getConfigParameter<double>("sr"); //! \ogs_file_param{material_property__porous_medium__porous_medium__capillary_pressure__BrookCorey__smax} const double Smax = config.getConfigParameter<double>("smax"); //! \ogs_file_param{material_property__porous_medium__porous_medium__capillary_pressure__BrookCorey__m} const double m = config.getConfigParameter<double>("m"); if (m < 1.0) // m >= 1 { OGS_FATAL( "The exponent parameter of BrookCorey capillary pressure " "saturation model, m, must not be smaller than 1"); } //! \ogs_file_param{material_property__porous_medium__porous_medium__capillary_pressure__BrookCorey__pc_max} const double Pc_max = config.getConfigParameter<double>("pc_max"); return std::unique_ptr<CapillaryPressureSaturation>( new BrookCoreyCapillaryPressureSaturation(pd, Sr, Smax, m, Pc_max)); }
void ignoreOtherLinearSolvers(const BaseLib::ConfigTree &config, const std::string &solver_name) { for (auto const& s : known_linear_solvers) { if (s!=solver_name) config.ignoreConfigParameter(s); } }
ProjectData::ProjectData(BaseLib::ConfigTree const& project_config, std::string const& project_directory, std::string const& output_directory) { std::string const geometry_file = BaseLib::copyPathToFileName( //! \ogs_file_param{prj__geometry} project_config.getConfigParameter<std::string>("geometry"), project_directory); detail::readGeometry(geometry_file, *_geoObjects); { //! \ogs_file_param{prj__mesh} auto const mesh_param = project_config.getConfigParameter("mesh"); std::string const mesh_file = BaseLib::copyPathToFileName( mesh_param.getValue<std::string>(), project_directory); MeshLib::Mesh* const mesh = MeshLib::IO::readMeshFromFile(mesh_file); if (!mesh) { OGS_FATAL("Could not read mesh from \'%s\' file. No mesh added.", mesh_file.c_str()); } if (auto const axially_symmetric = //! \ogs_file_attr{prj__mesh__axially_symmetric} mesh_param.getConfigAttributeOptional<bool>("axially_symmetric")) { mesh->setAxiallySymmetric(*axially_symmetric); } _mesh_vec.push_back(mesh); } //! \ogs_file_param{prj__curves} parseCurves(project_config.getConfigSubtreeOptional("curves")); //! \ogs_file_param{prj__parameters} parseParameters(project_config.getConfigSubtree("parameters")); //! \ogs_file_param{prj__process_variables} parseProcessVariables(project_config.getConfigSubtree("process_variables")); //! \ogs_file_param{prj__processes} parseProcesses(project_config.getConfigSubtree("processes"), project_directory, output_directory); //! \ogs_file_param{prj__linear_solvers} parseLinearSolvers(project_config.getConfigSubtree("linear_solvers")); //! \ogs_file_param{prj__nonlinear_solvers} parseNonlinearSolvers(project_config.getConfigSubtree("nonlinear_solvers")); //! \ogs_file_param{prj__time_loop} parseTimeLoop(project_config.getConfigSubtree("time_loop"), output_directory); }
std::unique_ptr<RelativePermeability> createRelativePermeabilityModel( BaseLib::ConfigTree const& config) { //! \ogs_file_param{material__porous_medium__relative_permeability__type} auto const type = config.peekConfigParameter<std::string>("type"); if (type == "WettingPhaseVanGenuchten") { return createWettingPhaseVanGenuchten(config); } if (type == "NonWettingPhaseVanGenuchten") { return createNonWettingPhaseVanGenuchten(config); } if (type == "WettingPhaseBrooksCoreyOilGas") { return createWettingPhaseBrooksCoreyOilGas(config); } if (type == "NonWettingPhaseBrooksCoreyOilGas") { return createNonWettingPhaseBrooksCoreyOilGas(config); } if (type == "Curve") { //! \ogs_file_param{material__porous_medium__relative_permeability__type} config.checkConfigParameter("type", "Curve"); //! \ogs_file_param{material__porous_medium__relative_permeability__Curve__curve} auto const& curve_config = config.getConfigSubtree("curve"); auto curve = MathLib::createPiecewiseLinearCurve<MathLib ::PiecewiseLinearInterpolation>(curve_config); return std::make_unique<RelativePermeabilityCurve>(std::move(curve)); } OGS_FATAL( "The relative permeability model %s is unavailable.\n" "The available models are:" "\n\tWettingPhaseVanGenuchten," "\n\tNonWettingPhaseVanGenuchten," "\n\tWettingPhaseBrooksCoreyOilGas," "\n\tNonWettingPhaseBrooksCoreyOilGas,", "\n\tCurve.\n", type.data()); }
static std::tuple<BoreholeGeometry, RefrigerantProperties, GroutParameters, FlowAndTemperatureControl, PipeConfigurationCoaxial> parseBHECoaxialConfig( BaseLib::ConfigTree const& config, std::map<std::string, std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> const& curves) { auto const borehole_geometry = //! \ogs_file_param{prj__processes__process__HEAT_TRANSPORT_BHE__borehole_heat_exchangers__borehole_heat_exchanger__borehole} createBoreholeGeometry(config.getConfigSubtree("borehole")); //! \ogs_file_param{prj__processes__process__HEAT_TRANSPORT_BHE__borehole_heat_exchangers__borehole_heat_exchanger__pipes} auto const& pipes_config = config.getConfigSubtree("pipes"); //! \ogs_file_param{prj__processes__process__HEAT_TRANSPORT_BHE__borehole_heat_exchangers__borehole_heat_exchanger__pipes__outer} Pipe const outer_pipe = createPipe(pipes_config.getConfigSubtree("outer")); Pipe const inner_pipe = //! \ogs_file_param{prj__processes__process__HEAT_TRANSPORT_BHE__borehole_heat_exchangers__borehole_heat_exchanger__pipes__inner} createPipe(pipes_config.getConfigSubtree("inner")); const auto pipe_longitudinal_dispersion_length = //! \ogs_file_param{prj__processes__process__HEAT_TRANSPORT_BHE__borehole_heat_exchangers__borehole_heat_exchanger__pipes__longitudinal_dispersion_length} pipes_config.getConfigParameter<double>( "longitudinal_dispersion_length"); PipeConfigurationCoaxial const pipes{inner_pipe, outer_pipe, pipe_longitudinal_dispersion_length}; //! \ogs_file_param{prj__processes__process__HEAT_TRANSPORT_BHE__borehole_heat_exchangers__borehole_heat_exchanger__grout} auto const grout = createGroutParameters(config.getConfigSubtree("grout")); auto const refrigerant = //! \ogs_file_param{prj__processes__process__HEAT_TRANSPORT_BHE__borehole_heat_exchangers__borehole_heat_exchanger__refrigerant} createRefrigerantProperties(config.getConfigSubtree("refrigerant")); auto const flowAndTemperatureControl = createFlowAndTemperatureControl( //! \ogs_file_param{prj__processes__process__HEAT_TRANSPORT_BHE__borehole_heat_exchangers__borehole_heat_exchanger__flow_and_temperature_control} config.getConfigSubtree("flow_and_temperature_control"), curves, refrigerant); return {borehole_geometry, refrigerant, grout, flowAndTemperatureControl, pipes}; }
std::unique_ptr<Process> createTESProcess( MeshLib::Mesh& mesh, std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler, std::vector<ProcessVariable> const& variables, std::vector<std::unique_ptr<ParameterBase>> const& parameters, unsigned const integration_order, BaseLib::ConfigTree const& config) { //! \ogs_file_param{prj__processes__process__type} config.checkConfigParameter("type", "TES"); DBUG("Create TESProcess."); //! \ogs_file_param{prj__processes__process__TES__process_variables} auto const pv_config = config.getConfigSubtree("process_variables"); auto per_process_variables = findProcessVariables( variables, pv_config, { //! \ogs_file_param_special{prj__processes__process__TES__process_variables__fluid_pressure} "fluid_pressure", //! \ogs_file_param_special{prj__processes__process__TES__process_variables__temperature} "temperature", //! \ogs_file_param_special{prj__processes__process__TES__process_variables__vapour_mass_fraction} "vapour_mass_fraction"}); std::vector<std::vector<std::reference_wrapper<ProcessVariable>>> process_variables; process_variables.push_back(std::move(per_process_variables)); SecondaryVariableCollection secondary_variables; NumLib::NamedFunctionCaller named_function_caller( {"TES_pressure", "TES_temperature", "TES_vapour_mass_fraction"}); ProcessLib::createSecondaryVariables(config, secondary_variables, named_function_caller); return std::make_unique<TESProcess>( mesh, std::move(jacobian_assembler), parameters, integration_order, std::move(process_variables), std::move(secondary_variables), std::move(named_function_caller), config); }
std::unique_ptr<InitialCondition> createUniformInitialCondition( BaseLib::ConfigTree const& config, int const /*n_components*/) { config.checkConfParam("type", "Uniform"); auto value = config.getConfParam<double>("value"); DBUG("Using value %g", value); return std::unique_ptr<InitialCondition>( new UniformInitialCondition(value)); }
void createSecondaryVariables( BaseLib::ConfigTree const& config, SecondaryVariableCollection& secondary_variables, NumLib::NamedFunctionCaller& named_function_caller) { auto sec_vars_config = //! \ogs_file_param{prj__processes__process__secondary_variables} config.getConfigSubtreeOptional("secondary_variables"); if (!sec_vars_config) return; for ( auto sec_var_config : //! \ogs_file_param{prj__processes__process__secondary_variables__secondary_variable} sec_vars_config->getConfigSubtreeList("secondary_variable")) { auto const type = //! \ogs_file_attr{prj__processes__process__secondary_variables__secondary_variable__type} sec_var_config.getConfigAttribute<std::string>("type"); auto const internal_name = //! \ogs_file_attr{prj__processes__process__secondary_variables__secondary_variable__internal_name} sec_var_config.getConfigAttribute<std::string>("internal_name"); auto const output_name = //! \ogs_file_attr{prj__processes__process__secondary_variables__secondary_variable__output_name} sec_var_config.getConfigAttribute<std::string>("output_name"); secondary_variables.addNameMapping(internal_name, output_name); if (type == "static") { // alright } else if (type == "dynamic") { auto const& sink_fct = internal_name; for ( auto const plug : //! \ogs_file_param{prj__processes__process__secondary_variables__secondary_variable__plug} sec_var_config.getConfigParameterList("plug")) { auto const sink_arg = //! \ogs_file_attr{prj__processes__process__secondary_variables__secondary_variable__plug__sink_arg} plug.getConfigAttribute<std::string>("sink_arg"); auto const source_fct = //! \ogs_file_attr{prj__processes__process__secondary_variables__secondary_variable__plug__source_fct} plug.getConfigAttribute<std::string>("source_fct"); named_function_caller.plug(sink_fct, sink_arg, source_fct); } } } }
std::unique_ptr<PhaseFieldIrreversibleDamageOracleBoundaryCondition> createPhaseFieldIrreversibleDamageOracleBoundaryCondition( BaseLib::ConfigTree const& config, NumLib::LocalToGlobalIndexMap const& dof_table, MeshLib::Mesh const& mesh, int const variable_id, int const component_id) { DBUG( "Constructing PhaseFieldIrreversibleDamageOracleBoundaryCondition from " "config."); //! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__type} config.checkConfigParameter( "type", "PhaseFieldIrreversibleDamageOracleBoundaryCondition"); return std::make_unique< PhaseFieldIrreversibleDamageOracleBoundaryCondition>( dof_table, mesh, variable_id, component_id); }
std::vector<std::reference_wrapper<ProcessVariable>> findProcessVariables( std::vector<ProcessVariable> const& variables, BaseLib::ConfigTree const& process_config, std::initializer_list<std::string> tag_names) { std::vector<std::reference_wrapper<ProcessVariable>> vars; vars.reserve(tag_names.size()); //! \ogs_file_param{process__process_variables} auto const pv_conf = process_config.getConfigSubtree("process_variables"); for (auto const& tag : tag_names) { vars.emplace_back(findProcessVariable(variables, pv_conf, tag)); } return vars; }
std::unique_ptr<FractureModelBase<DisplacementDim>> createMohrCoulomb( std::vector<std::unique_ptr<ProcessLib::ParameterBase>> const& parameters, BaseLib::ConfigTree const& config) { //! \ogs_file_param{material__fracture_model__type} config.checkConfigParameter("type", "MohrCoulomb"); DBUG("Create MohrCoulomb material"); auto& Kn = ProcessLib::findParameter<double>( //! \ogs_file_param_special{material__fracture_model__MohrCoulomb__normal_stiffness} config, "normal_stiffness", parameters, 1); auto& Ks = ProcessLib::findParameter<double>( //! \ogs_file_param_special{material__fracture_model__MohrCoulomb__shear_stiffness} config, "shear_stiffness", parameters, 1); auto& friction_angle = ProcessLib::findParameter<double>( //! \ogs_file_param_special{material__fracture_model__MohrCoulomb__friction_angle} config, "friction_angle", parameters, 1); auto& dilatancy_angle = ProcessLib::findParameter<double>( //! \ogs_file_param_special{material__fracture_model__MohrCoulomb__dilatancy_angle} config, "dilatancy_angle", parameters, 1); auto& cohesion = ProcessLib::findParameter<double>( //! \ogs_file_param_special{material__fracture_model__MohrCoulomb__cohesion} config, "cohesion", parameters, 1); auto const penalty_aperture_cutoff = //! \ogs_file_param{material__fracture_model__MohrCoulomb__penalty_aperture_cutoff} config.getConfigParameter<double>("penalty_aperture_cutoff"); auto const tension_cutoff = //! \ogs_file_param{material__fracture_model__MohrCoulomb__tension_cutoff} config.getConfigParameter<bool>("tension_cutoff"); typename MohrCoulomb<DisplacementDim>::MaterialProperties mp{ Kn, Ks, friction_angle, dilatancy_angle, cohesion}; return std::make_unique<MohrCoulomb<DisplacementDim>>( penalty_aperture_cutoff, tension_cutoff, mp); }
std::unique_ptr<NodalSourceTerm> createNodalSourceTerm( BaseLib::ConfigTree const& config, const NumLib::LocalToGlobalIndexMap& dof_table, std::size_t const mesh_id, std::size_t const node_id, const int variable_id, const int component_id, std::vector<std::unique_ptr<ProcessLib::ParameterBase>> const& parameters) { DBUG("Constructing NodalSourceTerm from config."); //! \ogs_file_param{prj__process_variables__process_variable__source_terms__source_term__type} config.checkConfigParameter("type", "Nodal"); //! \ogs_file_param{prj__process_variables__process_variable__source_terms__source_term__Nodal__parameter} auto const param_name = config.getConfigParameter<std::string>("parameter"); DBUG("Using parameter %s as nodal source term.", param_name.c_str()); auto& param = findParameter<double>(param_name, parameters, 1); return std::make_unique<NodalSourceTerm>( dof_table, mesh_id, node_id, variable_id, component_id, param); }
std::unique_ptr<CentralDifferencesJacobianAssembler> createCentralDifferencesJacobianAssembler(BaseLib::ConfigTree const& config) { //! \ogs_file_param{prj__processes__process__jacobian_assembler__type} config.checkConfigParameter("type", "CentralDifferences"); // TODO make non-optional. //! \ogs_file_param{prj__processes__process__jacobian_assembler__relative_epsilons} auto rel_eps = config.getConfigParameterOptional<std::vector<double>>( "relative_epsilons"); //! \ogs_file_param{prj__processes__process__jacobian_assembler__component_magnitudes} auto comp_mag = config.getConfigParameterOptional<std::vector<double>>( "component_magnitudes"); if (!!rel_eps != !!comp_mag) { OGS_FATAL( "Either both or none of <relative_epsilons> and " "<component_magnitudes> have to be specified."); } std::vector<double> abs_eps; if (rel_eps) { if (rel_eps->size() != comp_mag->size()) { OGS_FATAL( "The numbers of components of <relative_epsilons> and " "<component_magnitudes> do not match."); } abs_eps.resize(rel_eps->size()); for (std::size_t i=0; i<rel_eps->size(); ++i) { abs_eps[i] = (*rel_eps)[i] * (*comp_mag)[i]; } } else { // By default 1e-8 is used as epsilon for all components. // TODO: remove this default value. abs_eps.emplace_back(1e-8); } return std::unique_ptr<CentralDifferencesJacobianAssembler>( new CentralDifferencesJacobianAssembler(std::move(abs_eps))); }
std::unique_ptr<DirichletBoundaryCondition> createDirichletBoundaryCondition( BaseLib::ConfigTree const& config, std::vector<std::size_t>&& mesh_node_ids, NumLib::LocalToGlobalIndexMap const& dof_table, std::size_t const mesh_id, int const variable_id, int const component_id, const std::vector<std::unique_ptr<ProcessLib::ParameterBase>>& parameters) { DBUG("Constructing DirichletBoundaryCondition from config."); //! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__type} config.checkConfigParameter("type", "Dirichlet"); //! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__Dirichlet__parameter} auto const param_name = config.getConfigParameter<std::string>("parameter"); DBUG("Using parameter %s", param_name.c_str()); auto& param = findParameter<double>(param_name, parameters, 1); return std::unique_ptr<DirichletBoundaryCondition>( new DirichletBoundaryCondition(param, std::move(mesh_node_ids), dof_table, mesh_id, variable_id, component_id)); }
void EigenLinearSolver::setOption(BaseLib::ConfigTree const& option) { ignoreOtherLinearSolvers(option, "eigen"); //! \ogs_file_param{linear_solver__eigen} auto const ptSolver = option.getConfigSubtreeOptional("eigen"); if (!ptSolver) return; if (auto solver_type = //! \ogs_file_param{linear_solver__eigen__solver_type} ptSolver->getConfigParameterOptional<std::string>("solver_type")) { _option.solver_type = _option.getSolverType(*solver_type); } if (auto precon_type = //! \ogs_file_param{linear_solver__eigen__precon_type} ptSolver->getConfigParameterOptional<std::string>("precon_type")) { _option.precon_type = _option.getPreconType(*precon_type); } if (auto error_tolerance = //! \ogs_file_param{linear_solver__eigen__error_tolerance} ptSolver->getConfigParameterOptional<double>("error_tolerance")) { _option.error_tolerance = *error_tolerance; } if (auto max_iteration_step = //! \ogs_file_param{linear_solver__eigen__max_iteration_step} ptSolver->getConfigParameterOptional<int>("max_iteration_step")) { _option.max_iterations = *max_iteration_step; } if (auto scaling = //! \ogs_file_param{linear_solver__eigen__scaling} ptSolver->getConfigParameterOptional<bool>("scaling")) { #ifdef USE_EIGEN_UNSUPPORTED _option.scaling = *scaling; #else OGS_FATAL( "The code is not compiled with the Eigen unsupported modules. " "scaling is not available."); #endif } }
std::unique_ptr<RobinBoundaryCondition> createRobinBoundaryCondition( BaseLib::ConfigTree const& config, MeshLib::Mesh const& bc_mesh, NumLib::LocalToGlobalIndexMap const& dof_table, int const variable_id, int const component_id, unsigned const integration_order, unsigned const shapefunction_order, unsigned const global_dim, std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters) { DBUG("Constructing RobinBcConfig from config."); //! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__type} config.checkConfigParameter("type", "Robin"); //! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__Robin__alpha} auto const alpha_name = config.getConfigParameter<std::string>("alpha"); //! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__Robin__u_0} auto const u_0_name = config.getConfigParameter<std::string>("u_0"); auto const& alpha = ParameterLib::findParameter<double>(alpha_name, parameters, 1); auto const& u_0 = ParameterLib::findParameter<double>(u_0_name, parameters, 1); // In case of partitioned mesh the boundary could be empty, i.e. there is no // boundary condition. #ifdef USE_PETSC // This can be extracted to createBoundaryCondition() but then the config // parameters are not read and will cause an error. // TODO (naumov): Add a function to ConfigTree for skipping the tags of the // subtree and move the code up in createBoundaryCondition(). if (bc_mesh.getDimension() == 0 && bc_mesh.getNumberOfNodes() == 0 && bc_mesh.getNumberOfElements() == 0) { return nullptr; } #endif // USE_PETSC return std::make_unique<RobinBoundaryCondition>( integration_order, shapefunction_order, dof_table, variable_id, component_id, global_dim, bc_mesh, RobinBoundaryConditionData{alpha, u_0}); }