72 std::string
const& name,
74 std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
75 std::vector<ProcessVariable>
const& variables,
76 std::vector<std::unique_ptr<ParameterLib::ParameterBase>>
const& parameters,
77 unsigned const integration_order,
79 std::vector<std::unique_ptr<MeshLib::Mesh>>
const& meshes,
80 std::map<
int, std::shared_ptr<MaterialPropertyLib::Medium>>
const& media,
81 std::unique_ptr<ChemistryLib::ChemicalSolverInterface>&&
82 chemical_solver_interface)
87 DBUG(
"Create ComponentTransportProcess.");
89 auto const coupling_scheme =
93 const bool use_monolithic_scheme = (coupling_scheme !=
"staggered");
100 std::vector<std::vector<std::reference_wrapper<ProcessVariable>>>
105 variables, pv_config,
113 variables, pv_config,
115 "temperature",
true );
116 bool const isothermal = temperature_variable.empty();
119 assert(temperature_variable.size() == 1);
120 collected_process_variables.insert(
121 ++collected_process_variables.begin(), temperature_variable[0]);
125 auto it = std::find_if(
126 collected_process_variables.cbegin(),
127 collected_process_variables.cend(),
128 [](std::reference_wrapper<ProcessLib::ProcessVariable>
const& pv)
129 { return pv.get().getNumberOfGlobalComponents() != 1; });
131 if (it != collected_process_variables.end())
134 "Number of components for process variable '{:s}' should be 1 "
138 it->get().getNumberOfGlobalComponents());
143 if (use_monolithic_scheme)
148 "Currently, non-isothermal component transport process can "
149 "only be simulated in staggered scheme.");
152 process_variables.push_back(std::move(collected_process_variables));
156 std::vector<std::reference_wrapper<ProcessLib::ProcessVariable>>
157 per_process_variable;
159 if (!chemical_solver_interface)
161 for (
auto& pv : collected_process_variables)
163 per_process_variable.emplace_back(pv);
164 process_variables.push_back(std::move(per_process_variable));
169 auto sort_by_component =
170 [&per_process_variable,
171 collected_process_variables](
auto const& c_name)
173 auto pv = std::find_if(collected_process_variables.begin(),
174 collected_process_variables.end(),
175 [&c_name](
auto const& v) ->
bool
176 { return v.get().getName() == c_name; });
178 if (pv == collected_process_variables.end())
181 "Component {:s} given in "
182 "<chemical_system>/<solution>/"
183 "<components> is not found in specified "
184 "coupled processes (see "
185 "<process>/<process_variables>/"
190 per_process_variable.emplace_back(*pv);
191 return std::move(per_process_variable);
194 auto const components =
195 chemical_solver_interface->getComponentList();
197 per_process_variable.emplace_back(collected_process_variables[0]);
198 process_variables.push_back(std::move(per_process_variable));
202 per_process_variable.emplace_back(
203 collected_process_variables[1]);
204 process_variables.push_back(std::move(per_process_variable));
207 assert(components.size() + (isothermal ? 1 : 2) ==
208 collected_process_variables.size());
209 std::transform(components.begin(), components.end(),
210 std::back_inserter(process_variables),
216 std::vector<double>
const b =
219 assert(!b.empty() && b.size() < 4);
221 Eigen::VectorXd specific_body_force(b.size());
222 int const mesh_space_dimension =
224 if (
static_cast<int>(b.size()) != mesh_space_dimension)
227 "specific body force (gravity vector) has {:d} components, mesh "
229 b.size(), mesh_space_dimension);
234 std::copy_n(b.data(), b.size(), specific_body_force.data());
237 bool const non_advective_form =
241 bool chemically_induced_porosity_change =
249 config,
"temperature_field", parameters, 1, &mesh);
250 if (!isothermal && temperature_field !=
nullptr)
252 OGS_FATAL(
"Temperature field is set for non-isothermal setup.")
264 DBUG(
"Check the media properties of ComponentTransport process ...");
266 DBUG(
"Media properties verified.");
272 auto const aperture_config =
279 *aperture_config,
"parameter", parameters, 1);
282 auto const is_linear =
286 auto const ls_compute_only_upon_timestep_change =
289 "linear_solver_compute_only_upon_timestep_change",
false);
293 std::vector<Eigen::VectorXd> projected_specific_body_force_vectors;
294 projected_specific_body_force_vectors.reserve(rotation_matrices.size());
296 std::transform(rotation_matrices.begin(), rotation_matrices.end(),
297 std::back_inserter(projected_specific_body_force_vectors),
298 [&specific_body_force](
const auto& R)
299 { return R * R.transpose() * specific_body_force; });
302 std::move(media_map),
306 chemically_induced_porosity_change,
307 chemical_solver_interface.get(),
308 std::move(lookup_table),
309 std::move(stabilizer),
310 projected_specific_body_force_vectors,
311 mesh_space_dimension,
312 *aperture_size_parameter,
320 std::unique_ptr<ProcessLib::SurfaceFluxData> surfaceflux;
321 auto surfaceflux_config =
324 if (surfaceflux_config)
327 *surfaceflux_config, meshes);
330 return std::make_unique<ComponentTransportProcess>(
331 std::move(name), mesh, std::move(jacobian_assembler), parameters,
332 integration_order, std::move(process_variables),
333 std::move(process_data), std::move(secondary_variables),
334 use_monolithic_scheme, std::move(surfaceflux),
335 std::move(chemical_solver_interface), is_linear,
336 ls_compute_only_upon_timestep_change);