73 std::string
const& name,
75 std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
76 std::vector<ProcessVariable>
const& variables,
77 std::vector<std::unique_ptr<ParameterLib::ParameterBase>>
const& parameters,
78 unsigned const integration_order,
80 std::vector<std::unique_ptr<MeshLib::Mesh>>
const& meshes,
81 std::map<
int, std::shared_ptr<MaterialPropertyLib::Medium>>
const& media,
82 std::unique_ptr<ChemistryLib::ChemicalSolverInterface>&&
83 chemical_solver_interface)
88 DBUG(
"Create ComponentTransportProcess.");
90 auto const coupling_scheme =
94 const bool use_monolithic_scheme = (coupling_scheme !=
"staggered");
101 std::vector<std::vector<std::reference_wrapper<ProcessVariable>>>
106 variables, pv_config,
114 variables, pv_config,
116 "temperature",
true );
117 bool const isothermal = temperature_variable.empty();
120 assert(temperature_variable.size() == 1);
121 collected_process_variables.insert(
122 ++collected_process_variables.begin(), temperature_variable[0]);
126 auto it = std::find_if(
127 collected_process_variables.cbegin(),
128 collected_process_variables.cend(),
129 [](std::reference_wrapper<ProcessLib::ProcessVariable>
const& pv)
130 { return pv.get().getNumberOfGlobalComponents() != 1; });
132 if (it != collected_process_variables.end())
135 "Number of components for process variable '{:s}' should be 1 "
139 it->get().getNumberOfGlobalComponents());
144 if (use_monolithic_scheme)
149 "Currently, non-isothermal component transport process can "
150 "only be simulated in staggered scheme.");
153 process_variables.push_back(std::move(collected_process_variables));
157 std::vector<std::reference_wrapper<ProcessLib::ProcessVariable>>
158 per_process_variable;
160 if (!chemical_solver_interface)
162 for (
auto& pv : collected_process_variables)
164 per_process_variable.emplace_back(pv);
165 process_variables.push_back(std::move(per_process_variable));
170 auto sort_by_component =
171 [&per_process_variable,
172 collected_process_variables](
auto const& c_name)
174 auto pv = std::find_if(collected_process_variables.begin(),
175 collected_process_variables.end(),
176 [&c_name](
auto const& v) ->
bool
177 { return v.get().getName() == c_name; });
179 if (pv == collected_process_variables.end())
182 "Component {:s} given in "
183 "<chemical_system>/<solution>/"
184 "<components> is not found in specified "
185 "coupled processes (see "
186 "<process>/<process_variables>/"
191 per_process_variable.emplace_back(*pv);
192 return std::move(per_process_variable);
195 auto const components =
196 chemical_solver_interface->getComponentList();
198 per_process_variable.emplace_back(collected_process_variables[0]);
199 process_variables.push_back(std::move(per_process_variable));
203 per_process_variable.emplace_back(
204 collected_process_variables[1]);
205 process_variables.push_back(std::move(per_process_variable));
208 assert(components.size() + (isothermal ? 1 : 2) ==
209 collected_process_variables.size());
210 std::transform(components.begin(), components.end(),
211 std::back_inserter(process_variables),
217 std::vector<double>
const b =
220 assert(!b.empty() && b.size() < 4);
222 Eigen::VectorXd specific_body_force(b.size());
223 int const mesh_space_dimension =
225 if (
static_cast<int>(b.size()) != mesh_space_dimension)
228 "specific body force (gravity vector) has {:d} components, mesh "
230 b.size(), mesh_space_dimension);
235 std::copy_n(b.data(), b.size(), specific_body_force.data());
238 bool const non_advective_form =
242 bool chemically_induced_porosity_change =
250 config,
"temperature_field", parameters, 1, &mesh);
251 if (!isothermal && temperature_field !=
nullptr)
253 OGS_FATAL(
"Temperature field is set for non-isothermal setup.")
265 DBUG(
"Check the media properties of ComponentTransport process ...");
267 DBUG(
"Media properties verified.");
273 auto const aperture_config =
280 *aperture_config,
"parameter", parameters, 1);
283 auto const is_linear =
287 auto const ls_compute_only_upon_timestep_change =
290 "linear_solver_compute_only_upon_timestep_change",
false);
294 std::vector<Eigen::VectorXd> projected_specific_body_force_vectors;
295 projected_specific_body_force_vectors.reserve(rotation_matrices.size());
297 std::transform(rotation_matrices.begin(), rotation_matrices.end(),
298 std::back_inserter(projected_specific_body_force_vectors),
299 [&specific_body_force](
const auto& R)
300 { return R * R.transpose() * specific_body_force; });
303 std::move(media_map),
307 chemically_induced_porosity_change,
308 chemical_solver_interface.get(),
309 std::move(lookup_table),
310 std::move(stabilizer),
311 projected_specific_body_force_vectors,
312 mesh_space_dimension,
313 *aperture_size_parameter,
321 std::unique_ptr<ProcessLib::SurfaceFluxData> surfaceflux;
322 auto surfaceflux_config =
325 if (surfaceflux_config)
328 *surfaceflux_config, meshes);
331 return std::make_unique<ComponentTransportProcess>(
332 std::move(name), mesh, std::move(jacobian_assembler), parameters,
333 integration_order, std::move(process_variables),
334 std::move(process_data), std::move(secondary_variables),
335 use_monolithic_scheme, std::move(surfaceflux),
336 std::move(chemical_solver_interface), is_linear,
337 ls_compute_only_upon_timestep_change);