8 #ifndef SRC_ASSEMBLY_LMH_OLD_HH_
9 #define SRC_ASSEMBLY_LMH_OLD_HH_
47 velocity_interpolation_quad_(dim, 0),
57 auto fe = ad_->dh_->ds()->fe()[
Dim<dim>{}];
59 loc_side_dofs = fe_system->
fe_dofs(0);
60 loc_ele_dof = fe_system->
fe_dofs(1)[0];
61 loc_edge_dofs = fe_system->
fe_dofs(2);
64 .error(
"Mortar methods are not supported in Lumped Mixed-Hybrid Method.");
73 schur_offset_ = loc_edge_dofs[0];
74 reconstructed_solution_.zeros(schur_offset_);
99 arma::vec schur_solution = ad_->p_edge_solution.get_subvec(loc_schur_.row_dofs);
101 loc_system_.reconstruct_solution_schur(schur_offset_, schur_solution, reconstructed_solution_);
106 ad_->full_solution.set_subvec(loc_system_.row_dofs.head(schur_offset_), reconstructed_solution_);
107 ad_->full_solution.set_subvec(loc_system_.row_dofs.tail(loc_schur_.row_dofs.n_elem), schur_solution);
113 save_local_system_ =
false;
114 bc_fluxes_reconstruted =
false;
118 loc_system_.compute_schur_complement(schur_offset_, loc_schur_,
true);
122 loc_schur_.eliminate_solution();
123 ad_->lin_sys_schur->set_local_system(loc_schur_, ad_->dh_cr_->get_local_to_global_map());
159 if(bc_fluxes_reconstruted)
163 auto ls = ad_->seepage_bc_systems.find(dh_cell.
elm_idx());
164 if (ls != ad_->seepage_bc_systems.end())
166 arma::vec schur_solution = ad_->p_edge_solution.get_subvec(loc_schur_.row_dofs);
168 ls->second.reconstruct_solution_schur(schur_offset_, schur_solution, reconstructed_solution_);
172 bc_fluxes_reconstruted =
true;
182 if(save_local_system_)
183 ad_->seepage_bc_systems[dh_cell.
elm_idx()] = loc_system_;
217 const unsigned int p =
size()+i;
219 const unsigned int t = dh_neighb_cell.
n_dofs() - dh_neighb_cr_cell.
n_dofs() + neighb_side.side().side_idx();
223 const unsigned int tt = dh_cr_cell.
n_dofs()+i;
225 [neighb_side.side().side_idx()];
229 loc_system_.reset(dofs, dofs);
230 loc_schur_.reset(dofs_schur, dofs_schur);
237 dirichlet_edge.resize(ele->
n_sides());
239 unsigned int sidx = dh_side.side_idx();
240 dirichlet_edge[sidx] = 0;
243 if (dh_side.side().is_boundary()) {
244 double cross_section = af_->cross_section.value(ele.
centre(), ele);
247 ad_->balance->add_flux_values(ad_->water_balance_idx, dh_side,
248 {loc_system_.row_dofs[loc_side_dofs[sidx]]},
253 loc_system_.add_value(loc_side_dofs[sidx], loc_edge_dofs[sidx], 1.0);
254 loc_system_.add_value(loc_edge_dofs[sidx], loc_side_dofs[sidx], 1.0);
261 const unsigned int sidx = side.
side_idx();
262 const unsigned int side_row = loc_side_dofs[sidx];
263 const unsigned int edge_row = loc_edge_dofs[sidx];
271 double bc_pressure = af_->bc_pressure.value(b_ele.
centre(), b_ele);
272 loc_schur_.set_solution(sidx, bc_pressure);
273 dirichlet_edge[sidx] = 1;
277 double bc_flux = -af_->bc_flux.value(b_ele.
centre(), b_ele);
278 double bc_pressure = af_->bc_pressure.value(b_ele.
centre(), b_ele);
279 double bc_sigma = af_->bc_robin_sigma.value(b_ele.
centre(), b_ele);
281 dirichlet_edge[sidx] = 2;
282 loc_system_.add_value(edge_row, edge_row,
283 -b_ele.
measure() * bc_sigma * cross_section,
284 (bc_flux - bc_sigma * bc_pressure) * b_ele.
measure() * cross_section);
287 ad_->is_linear=
false;
289 char & switch_dirichlet = ad_->bc_switch_dirichlet[b_ele.
idx()];
290 double bc_pressure = af_->bc_switch_pressure.value(b_ele.
centre(), b_ele);
291 double bc_flux = -af_->bc_flux.value(b_ele.
centre(), b_ele);
292 double side_flux = bc_flux * b_ele.
measure() * cross_section;
295 if(use_dirichlet_switch){
296 if (switch_dirichlet) {
303 double solution_flux = reconstructed_solution_[side_row];
305 if ( solution_flux < side_flux) {
320 double solution_head = ad_->p_edge_solution.get(loc_schur_.row_dofs[sidx]);
322 if ( solution_head > bc_pressure) {
329 save_local_system_ = (bool) switch_dirichlet;
333 if (switch_dirichlet || ad_->force_no_neumann_bc ) {
335 loc_schur_.set_solution(sidx, bc_pressure);
336 dirichlet_edge[sidx] = 1;
339 loc_system_.add_value(edge_row, side_flux);
343 ad_->is_linear=
false;
345 double bc_pressure = af_->bc_pressure.value(b_ele.
centre(), b_ele);
346 double bc_switch_pressure = af_->bc_switch_pressure.value(b_ele.
centre(), b_ele);
347 double bc_flux = -af_->bc_flux.value(b_ele.
centre(), b_ele);
348 double bc_sigma = af_->bc_robin_sigma.value(b_ele.
centre(), b_ele);
350 double solution_head = ad_->p_edge_solution.get(loc_schur_.row_dofs[sidx]);
353 if (solution_head > bc_switch_pressure || ad_->force_no_neumann_bc) {
356 loc_system_.add_value(edge_row, edge_row,
357 -b_ele.
measure() * bc_sigma * cross_section,
358 b_ele.
measure() * cross_section * (bc_flux - bc_sigma * bc_pressure) );
362 double bc_total_flux = bc_flux + bc_sigma*(bc_switch_pressure - bc_pressure);
364 loc_system_.add_value(edge_row, bc_total_flux * b_ele.
measure() * cross_section);
368 THROW( ExcBCNotSupported() );
376 double cs = af_->cross_section.value(ele.
centre(), ele);
377 double conduct = af_->conductivity.value(ele.
centre(), ele);
378 double scale = 1 / cs /conduct;
386 auto ele = dh_cell.
elm();
393 for (
unsigned int k=0; k<qsize; k++)
394 for (
unsigned int i=0; i<ndofs; i++){
396 arma::dot(gravity_vec,velocity.value(i,k))
398 loc_system_.add_value(i, rhs_val);
400 for (
unsigned int j=0; j<ndofs; j++){
402 arma::dot(velocity.value(i,k),
403 (af_->anisotropy.value(ele.centre(), ele)).i()
404 * velocity.value(j,k))
407 loc_system_.add_value(i, j, mat_val);
438 for(
unsigned int side = 0; side < loc_side_dofs.size(); side++){
439 loc_system_.add_value(loc_ele_dof, loc_side_dofs[side], -1.0);
440 loc_system_.add_value(loc_side_dofs[side], loc_ele_dof, -1.0);
455 double alpha = 1.0 / ele->
n_sides();
456 double cross_section = af_->cross_section.value(ele.
centre(), ele);
457 double coef = alpha * ele.
measure() * cross_section;
459 double source = af_->water_source_density.value(ele.
centre(), ele)
460 + af_->extra_source.value(ele.
centre(), ele);
461 double source_term = coef * source;
464 double storativity = 0.0;
465 double time_term_diag = 0.0, time_term = 0.0, time_term_rhs = 0.0;
467 if(! ad_->use_steady_assembly_)
469 storativity = af_->storativity.value(ele.
centre(), ele)
470 + af_->extra_storativity.value(ele.
centre(), ele);
471 time_term = coef * storativity;
474 for (
unsigned int i=0; i<ele->
n_sides(); i++)
476 if(! ad_->use_steady_assembly_)
478 time_term_diag = time_term / ad_->time_step_;
479 time_term_rhs = time_term_diag * ad_->p_edge_solution_previous_time.get(loc_schur_.row_dofs[i]);
481 ad_->balance->add_mass_values(ad_->water_balance_idx, dh_cell,
482 {loc_system_.row_dofs[loc_edge_dofs[i]]}, {time_term}, 0);
488 ad_->balance->add_mass_values(ad_->water_balance_idx, dh_cell,
489 {loc_system_.row_dofs[loc_edge_dofs[i]]}, {0}, 0);
492 this->loc_system_.add_value(loc_edge_dofs[i], loc_edge_dofs[i],
494 -source_term - time_term_rhs);
496 ad_->balance->add_source_values(ad_->water_balance_idx, ele.
region().
bulk_idx(),
497 {loc_system_.row_dofs[loc_edge_dofs[i]]}, {0},{source_term});
515 unsigned int p =
size()+i;
518 ngh_values_.fe_side_values_.reinit(neighb_side.side());
519 nv = ngh_values_.fe_side_values_.normal_vector(0);
521 double value = af_->sigma.value( ele.
centre(), ele) *
522 2*af_->conductivity.value( ele.
centre(), ele) *
523 arma::dot(af_->anisotropy.value( ele.
centre(), ele)*nv, nv) *
524 af_->cross_section.value( neighb_side.centre(), ele_higher ) *
525 af_->cross_section.value( neighb_side.centre(), ele_higher ) /
526 af_->cross_section.value( ele.
centre(), ele ) *
527 neighb_side.measure();
529 loc_system_.add_value(loc_ele_dof, loc_ele_dof, -
value);
530 loc_system_.add_value(loc_ele_dof, p,
value);
531 loc_system_.add_value(p,loc_ele_dof,
value);
532 loc_system_.add_value(p,p, -
value);
549 double edge_scale = ele.
measure()
550 * af_->cross_section.value(ele.
centre(), ele)
553 double edge_source_term = edge_scale *
554 ( af_->water_source_density.value(ele.
centre(), ele)
555 + af_->extra_source.value(ele.
centre(), ele));
561 double edge_scale,
double edge_source_term)
565 double storativity = af_->storativity.value(ele.
centre(), ele)
566 + af_->extra_storativity.value(ele.
centre(), ele);
567 double new_pressure, old_pressure, time_term = 0.0;
569 for (
unsigned int i=0; i<ele->
n_sides(); i++) {
571 if( ! ad_->use_steady_assembly_)
573 new_pressure = ad_->p_edge_solution.get(loc_schur_.row_dofs[i]);
574 old_pressure = ad_->p_edge_solution_previous_time.get(loc_schur_.row_dofs[i]);
575 time_term = edge_scale * storativity / ad_->time_step_ * (new_pressure - old_pressure);
577 solution[loc_side_dofs[i]] += edge_source_term - time_term;
589 QGauss velocity_interpolation_quad_;
606 unsigned int loc_ele_dof;
611 unsigned int schur_offset_;
618 bool save_local_system_;
621 bool bc_fluxes_reconstruted;