55 output_fields += eq_data;
61 return it::Record(
"Output_DarcyMHSpecific",
"Specific Darcy flow MH output.")
63 "SPECIAL PURPOSE. Computes error norms of the solution, particulary suited for non-compatible coupling models.")
65 "Output file with raw data form MH module.")
76 .
description(
"Pressure solution - P0 interpolation.");
79 .
description(
"Pressure solution - P1 interpolation.");
82 .
description(
"Piezo head solution - P0 interpolation.");
85 .
description(
"Velocity solution - P0 interpolation.");
89 .
description(
"Subdomain ids of the domain decomposition.");
97 .
description(
"Error norm of the pressure solution. [Experimental]");
100 .
description(
"Error norm of the velocity solution. [Experimental]");
103 .
description(
"Error norm of the divergence of the velocity solution. [Experimental]");
118 output_fields.set_mesh(*
mesh_);
133 auto corner_ptr = make_shared< FieldFE<3, FieldValue<3>::Scalar> >();
159 if (in_rec_specific) {
164 if (in_rec_specific->opt_val(
"raw_flow_output", raw_output_file_path)) {
165 MessageOut() <<
"Opening raw output: " << raw_output_file_path <<
"\n";
168 }
INPUT_CATCH(FilePath::ExcFileOpen, FilePath::EI_Address_String, (*in_rec_specific))
248 START_TIMER(
"DarcyFlowMHOutput::make_element_scalar");
249 unsigned int sol_size;
254 for(
unsigned int i_ele : element_indices) {
269 START_TIMER(
"DarcyFlowMHOutput::make_element_vector");
273 auto multidim_assembler = AssemblyBase::create< AssemblyMH >(
darcy_flow->
data_);
275 for(
unsigned int i_ele : element_indices) {
278 flux_in_center = multidim_assembler[ele->dim() -1]->make_element_vector(ele);
281 for(
unsigned int j=0; j<3; j++)
ele_flux[3*i_ele + j]=flux_in_center[j];
288 START_TIMER(
"DarcyFlowMHOutput::make_corner_scalar");
289 unsigned int ndofs = max(
dh->
fe<1>()->n_dofs(), max(
dh->
fe<2>()->n_dofs(),
dh->
fe<3>()->n_dofs()));
290 unsigned int indices[ndofs];
318 START_TIMER(
"DarcyFlowMHOutput::make_node_scalar_param");
330 int* sum_elements =
new int [n_nodes];
331 int* sum_sides =
new int [n_nodes];
332 double* sum_ele_dist =
new double [n_nodes];
333 double* sum_side_dist =
new double [n_nodes];
337 bool count_elements =
true;
338 bool count_sides =
true;
344 for (
int i = 0; i < n_nodes; i++){
347 sum_ele_dist[i] = 0.0;
348 sum_side_dist[i] = 0.0;
355 for (
unsigned int li = 0; li < ele->n_nodes(); li++) {
356 node = ele->node[li];
360 ((node->
getX() - ele->centre()[ 0 ])*(node->
getX() - ele->centre()[ 0 ])) +
361 ((node->
getY() - ele->centre()[ 1 ])*(node->
getY() - ele->centre()[ 1 ])) +
362 ((node->
getZ() - ele->centre()[ 2 ])*(node->
getZ() - ele->centre()[ 2 ]))
364 sum_ele_dist[node_index] += dist;
365 sum_elements[node_index]++;
370 for (
unsigned int li = 0; li < side->n_nodes(); li++) {
371 node = side->node(li);
374 ((node->
getX() - side->centre()[ 0 ])*(node->
getX() - side->centre()[ 0 ])) +
375 ((node->
getY() - side->centre()[ 1 ])*(node->
getY() - side->centre()[ 1 ])) +
376 ((node->
getZ() - side->centre()[ 2 ])*(node->
getZ() - side->centre()[ 2 ]))
379 sum_side_dist[node_index] += dist;
380 sum_sides[node_index]++;
388 for (
unsigned int li = 0; li < ele->n_nodes(); li++) {
389 node = ele->node[li];
394 ((node->
getX() - ele->centre()[ 0 ])*(node->
getX() - ele->centre()[ 0 ])) +
395 ((node->
getY() - ele->centre()[ 1 ])*(node->
getY() - ele->centre()[ 1 ])) +
396 ((node->
getZ() - ele->centre()[ 2 ])*(node->
getZ() - ele->centre()[ 2 ]))
399 (1 - dist / (sum_ele_dist[node_index] + sum_side_dist[node_index])) /
400 (sum_elements[node_index] + sum_sides[node_index] - 1);
405 for (
unsigned int li = 0; li < side->n_nodes(); li++) {
406 node = side->node(li);
411 ((node->
getX() - side->centre()[ 0 ])*(node->
getX() - side->centre()[ 0 ])) +
412 ((node->
getY() - side->centre()[ 1 ])*(node->
getY() - side->centre()[ 1 ])) +
413 ((node->
getZ() - side->centre()[ 2 ])*(node->
getZ() - side->centre()[ 2 ]))
418 (1 - dist / (sum_ele_dist[node_index] + sum_side_dist[node_index])) /
419 (sum_sides[node_index] + sum_elements[node_index] - 1);
425 delete [] sum_elements;
427 delete [] sum_ele_dist;
428 delete [] sum_side_dist;
439 START_TIMER(
"DarcyFlowMHOutput::output_internal_flow_data");
446 raw_output_file <<
"// fields:\n//ele_id ele_presure flux_in_barycenter[3] n_sides side_pressures[n] side_fluxes[n] ns_side_neighbors[n] neighbors[n*ns] n_vb_neighbors vb_neighbors[n_vb]\n";
454 unsigned int undefined_ele_id = -1;
457 if(ele->n_neighs_vb > 0){
458 for (
unsigned int i = 0; i < ele->n_neighs_vb; i++){
461 auto search = neigh_vb_map.find(higher_ele->
id());
462 if(search != neigh_vb_map.end()){
464 search->second[ele->neigh_vb[i]->side()->el_idx()] = ele->id();
469 higher_ele_side_ngh[ele->neigh_vb[i]->side()->el_idx()] = ele->id();
470 neigh_vb_map[higher_ele->
id()] = higher_ele_side_ngh;
478 for (
unsigned int i = 0; i < 3; i++)
483 for (
unsigned int i = 0; i < ele->n_sides(); i++) {
486 for (
unsigned int i = 0; i < ele->n_sides(); i++) {
490 auto search_neigh = neigh_vb_map.end();
491 for (
unsigned int i = 0; i < ele->n_sides(); i++) {
492 unsigned int n_side_neighs = ele->side(i)->edge()->n_sides-1;
494 if(n_side_neighs == 0){
496 if(search_neigh == neigh_vb_map.end())
497 search_neigh = neigh_vb_map.find(ele->id());
499 if(search_neigh != neigh_vb_map.end())
500 if(search_neigh->second[i] != undefined_ele_id)
506 for (
unsigned int i = 0; i < ele->n_sides(); i++) {
508 if(ele->side(i)->edge()->n_sides > 1){
509 for (
unsigned int j = 0; j < edge->
n_sides; j++) {
510 if(edge->
side(j) != ele->side(i))
515 else if(search_neigh != neigh_vb_map.end()
516 && search_neigh->second[i] != undefined_ele_id){
523 for (
unsigned int i = 0; i < ele->n_neighs_vb; i++)
550 double pressure_error[2], velocity_error[2], div_error[2];
582 for (
unsigned int li = 0; li < ele->n_sides(); li++) {
583 fluxes[li] = result.
dh->
side_flux( *(ele->side( li ) ) );
588 arma::vec analytical(5);
592 double velocity_diff=0, divergence_diff=0, pressure_diff=0, diff;
596 double mean_x_squared=0;
597 for(
unsigned int i_node=0; i_node < ele->n_nodes(); i_node++ )
598 for(
unsigned int j_node=0; j_node < ele->n_nodes(); j_node++ )
600 mean_x_squared += (i_node == j_node ? 2.0 : 1.0) / ( 6 * dim )
601 * arma::dot( ele->node[i_node]->point(), ele->node[j_node]->point());
604 for(
unsigned int i_point=0; i_point < fe_values.
n_points(); i_point++) {
608 analytical = anal_sol.
value(q_point, ele->element_accessor() );
609 for(
unsigned int i=0; i< 3; i++) anal_flux[i] = analytical[i+1];
613 for(
unsigned int i_shape=0; i_shape < ele->n_sides(); i_shape++) {
616 diff += fluxes[ i_shape ] *
617 ( arma::dot( q_point, q_point )/ 2
619 - arma::dot( q_point, ele->node[oposite_node]->point() )
620 + arma::dot( ele->centre(), ele->node[oposite_node]->point() )
624 diff = - (1.0 / conductivity) * diff / dim / ele->measure() / cross + pressure_mean ;
625 diff = ( diff - analytical[0]);
626 pressure_diff += diff * diff * fe_values.
JxW(i_point);
630 flux_in_q_point.zeros();
631 for(
unsigned int i_shape=0; i_shape < ele->n_sides(); i_shape++) {
632 flux_in_q_point += fluxes[ i_shape ]
637 flux_in_q_point -= anal_flux;
638 velocity_diff += dot(flux_in_q_point, flux_in_q_point) * fe_values.
JxW(i_point);
642 for(
unsigned int i_shape=0; i_shape < ele->n_sides(); i_shape++) diff += fluxes[ i_shape ];
643 diff = ( diff / ele->measure() / cross - analytical[4]);
644 divergence_diff += diff * diff * fe_values.
JxW(i_point);
659 result.
div_error[dim-1] += divergence_diff;
672 const unsigned int order = 4;
737 unsigned int solution_size;
746 switch (ele->dim()) {
749 l2_diff_local<1>( ele, fe_values_1d, fv_rt1d, anal_sol_1d, result);
752 l2_diff_local<2>( ele, fe_values_2d, fv_rt2d, anal_sol_2d, result);
757 os <<
"l2 norm output\n\n" 758 <<
"pressure error 1d: " << sqrt(result.
pressure_error[0]) << endl
759 <<
"pressure error 2d: " << sqrt(result.
pressure_error[1]) << endl
760 <<
"velocity error 1d: " << sqrt(result.
velocity_error[0]) << endl
761 <<
"velocity error 2d: " << sqrt(result.
velocity_error[1]) << endl
762 <<
"masked velocity error 2d: " << sqrt(result.
mask_vel_error) <<endl
763 <<
"div error 1d: " << sqrt(result.
div_error[0]) << endl
764 <<
"div error 2d: " << sqrt(result.
div_error[1]);
void set_python_field_from_file(const FilePath &file_name, const string &func_name)
void get_solution_vector(double *&vec, unsigned int &vec_size) override
Field< 3, FieldValue< 3 >::VectorFixed > field_ele_flux
Class MappingP1 implements the affine transformation of the unit cell onto the actual cell...
Field< 3, FieldValue< 3 >::Scalar > velocity_diff
double JxW(const unsigned int point_no)
Return the product of Jacobian determinant and the quadrature weight at given quadrature point...
VectorSeqDouble ele_pressure
static auto subdomain(Mesh &mesh) -> IndexField
Declaration of class which handles the ordering of degrees of freedom (dof) and mappings between loca...
Output class for darcy_flow_mh model.
#define FOR_ELEMENT_NODES(i, j)
Field< 3, FieldValue< 3 >::Scalar > field_node_pressure
#define FOR_ELEMENTS(_mesh_, __i)
#define MessageOut()
Macro defining 'message' record of log.
VectorSeqDouble velocity_diff
void output(TimeStep step)
void make_element_vector(ElementSetRef element_indices)
std::string format(CStringRef format_str, ArgList args)
RegionSet get_region_set(const string &set_name) const
void compute_l2_difference()
void distribute_dofs(FiniteElement< 1, 3 > &fe1d, FiniteElement< 2, 3 > &fe2d, FiniteElement< 3, 3 > &fe3d, const unsigned int offset=0)
Distributes degrees of freedom on the mesh needed for the given finite elements.
Fields computed from the mesh data.
void make_corner_scalar(vector< double > &node_scalar)
Class FEValues calculates finite element data on the actual cells such as shape function values...
VectorSeqDouble pressure_diff
void chkerr(unsigned int ierr)
Replacement of new/delete operator in the spirit of xmalloc.
FieldPython< 3, FieldValue< 3 >::Vector > ExactSolution
const RegionDB & region_db() const
Field< 3, FieldValue< 3 >::Integer > subdomain
const TimeStep & step(int index=-1) const
FieldCommon & units(const UnitSI &units)
Set basic units of the field.
std::vector< unsigned int > all_element_idx_
std::shared_ptr< OutputTime > output_stream
std::shared_ptr< EqData > data_
unsigned int n_points()
Returns the number of quadrature points.
FiniteElement< dim, 3 > * fe() const
Returns finite element object for given space dimension.
void make_node_scalar_param(ElementSetRef element_indices)
Calculate nodes scalar, store it in double* node_scalars instead of node->scalar. ...
static unsigned int oposite_node(unsigned int sid)
Symmetric Gauss-Legendre quadrature formulae on simplices.
int id()
Returns id of the iterator. See VectorId documentation.
unsigned int size() const
Returns size of the container. This is independent of the allocated space.
void open_stream(Stream &stream) const
Discontinuous Lagrangean finite element on dim dimensional simplex.
Field< 3, FieldValue< 3 >::Scalar > field_ele_pressure
Transformed quadrature points.
Global macros to enhance readability and debugging, general constants.
unsigned int n_elements() const
static constexpr Mask equation_result
Match result fields. These are never given by input or copy of input.
OutputFields output_fields
double element_scalar(ElementFullIter &ele) const
temporary replacement for DofHandler accessor, scalar (pressure) on element
VectorSeqDouble ele_piezo_head
Raviart-Thomas element of order 0.
Definitions of basic Lagrangean finite elements with polynomial shape functions.
static constexpr Mask equation_external_output
Match an output field, that can be also copy of other field.
static auto region_id(Mesh &mesh) -> IndexField
void resize(unsigned int size)
Create shared pointer and PETSC vector with given size.
const Element * slave_iter() const
#define START_TIMER(tag)
Starts a timer with specified tag.
Provides the numbering of the finite element degrees of freedom on the computational mesh...
unsigned int index(const T *pointer) const
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm) const
static const Input::Type::Instance & get_input_type()
ofstream raw_output_file
Raw data output file.
static const Input::Type::Record & get_input_type_specific()
arma::vec::fixed< spacedim > shape_vector(const unsigned int function_no, const unsigned int point_no)
Return the value of the function_no-th shape function at the point_no-th quadrature point...
void output_internal_flow_data()
Dedicated class for storing path to input and output files.
Field< 3, FieldValue< 3 >::Scalar > field_ele_piezo_head
static std::shared_ptr< OutputTime > create_output_stream(const std::string &equation_name, Mesh &mesh, const Input::Record &in_rec)
This method delete all object instances of class OutputTime stored in output_streams vector...
Field< 3, FieldValue< 3 >::Integer > region_id
double side_flux(const Side &side) const
temporary replacement for DofHandler accessor, flux through given side
FieldCommon & description(const string &description)
Field< 3, FieldValue< 3 >::Scalar > pressure_diff
void get_dof_indices(const CellIterator &cell, unsigned int indices[]) const override
Returns the global indices of dofs associated to the cell.
ElementFullIter element() const
bool compute_errors_
Specific experimental error computing.
void set_field(const RegionSet &domain, FieldBasePtr field, double time=0.0)
void reinit(ElementFullIter &cell)
Update cell-dependent data (gradients, Jacobians etc.)
std::vector< int > velocity_mask
bool set_time(const TimeStep &time, LimitSide limit_side)
vector< Intersection > intersections
std::shared_ptr< FieldElementwise< spacedim, Value > > create_field(unsigned int n_comp)
Create and return shared pointer to FieldElementwise object.
Definitions of particular quadrature rules on simplices.
FieldCommon & name(const string &name)
Field< 3, FieldValue< 3 >::Scalar > div_diff
unsigned int n_nodes() const
vector< double > corner_pressure
mixed-hybrid model of linear Darcy flow, possibly unsteady.
void set_mesh(const Mesh &mesh)
bool is_field_output_time(const FieldCommon &field, TimeStep step) const
const Input::Type::Instance & make_output_type(const string &equation_name, const string &aditional_description="")
Field< 3, FieldValue< 3 >::Scalar > cross_section
Field< 3, FieldValue< 3 >::Scalar > conductivity
FieldCommon & flags(FieldFlag::Flags::Mask mask)
double side_scalar(const Side &side) const
temporary replacement for DofHandler accessor, scalar (pressure) on edge of the side ...
Class for representation SI units of Fields.
DarcyFlowMHOutput(DarcyMH *flow, Input::Record in_rec)
static UnitSI & dimensionless()
Returns dimensionless unit.
#define FOR_SIDES(_mesh_, it)
#define DebugOut()
Macro defining 'debug' record of log.
void make_element_scalar(ElementSetRef element_indices)
void l2_diff_local(ElementFullIter &ele, FEValues< dim, 3 > &fe_values, FEValues< dim, 3 > &fv_rt, ExactSolution &anal_sol, DiffData &result)
SideIter side(const unsigned int i) const
Definitions of Raviart-Thomas finite elements.
const unsigned int n_global_dofs() const
Getter for the number of all mesh dofs required by the given finite element.
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm)
NodeVector node_vector
Vector of nodes of the mesh.
FieldSet error_fields_for_output
ElementVector element
Vector of elements of the mesh.
void output()
Calculate values for output.
Transformed quadrature weights.
const MH_DofHandler & get_mh_dofhandler() override
Mixed-hybrid of steady Darcy flow with sources and variable density.
arma::vec::fixed< spacedim > point(const unsigned int point_no)
Return coordinates of the quadrature point in the actual cell system.