56 namespace it = Input::Type;
60 .
copy_values(OutputFields().make_output_field_selection(
"").close())
64 =
it::Record(
"DarcyMHOutput",
"Parameters of MH output.")
66 "Parameters of output stream.")
70 "Output file for water balance table.")
72 "SPECIAL PURPOSE. Computing errors pro non-compatible coupling.")
74 "Output file with raw data form MH module.");
113 auto ele_pressure_ptr=make_shared< FieldElementwise<3, FieldValue<3>::Scalar> >(
ele_pressure, 1);
121 auto corner_ptr = make_shared< FieldFE<3, FieldValue<3>::Scalar> >();
129 make_shared< FieldElementwise<3, FieldValue<3>::Scalar> >(
ele_piezo_head, 1));
133 make_shared< FieldElementwise<3, FieldValue<3>::VectorFixed> >(
ele_flux, 3));
137 for(
unsigned int i=0; i<
subdomains.size();i++)
140 make_shared< FieldElementwise<3, FieldValue<3>::Integer> >(
subdomains, 1));
160 if (in_rec.
opt_val(
"raw_flow_output", raw_output_file_path)) {
161 xprintf(
Msg,
"Opening raw output: %s\n",
string(raw_output_file_path).c_str() );
237 unsigned int sol_size;
263 flux_in_centre.zeros();
270 for (
unsigned int li = 0; li < ele->n_sides(); li++) {
271 flux_in_centre += dh.
side_flux( *(ele->side( li ) ) )
272 * fe_values.
RT0_value( ele, ele->centre(), li )
276 for(
unsigned int j=0; j<3; j++)
277 ele_flux[3*i_side+j]=flux_in_centre[j];
287 unsigned int ndofs = max(
dh->
fe<1>()->n_dofs(), max(
dh->
fe<2>()->n_dofs(),
dh->
fe<3>()->n_dofs()));
288 unsigned int indices[ndofs];
329 int* sum_elements =
new int [n_nodes];
330 int* sum_sides =
new int [n_nodes];
331 double* sum_ele_dist =
new double [n_nodes];
332 double* sum_side_dist =
new double [n_nodes];
336 bool count_elements =
true;
337 bool count_sides =
true;
343 for (
int i = 0; i < n_nodes; i++){
346 sum_ele_dist[i] = 0.0;
347 sum_side_dist[i] = 0.0;
354 for (
unsigned int li = 0; li < ele->n_nodes(); li++) {
355 node = ele->node[li];
359 ((node->
getX() - ele->centre()[ 0 ])*(node->
getX() - ele->centre()[ 0 ])) +
360 ((node->
getY() - ele->centre()[ 1 ])*(node->
getY() - ele->centre()[ 1 ])) +
361 ((node->
getZ() - ele->centre()[ 2 ])*(node->
getZ() - ele->centre()[ 2 ]))
363 sum_ele_dist[node_index] += dist;
364 sum_elements[node_index]++;
369 for (
unsigned int li = 0; li < side->n_nodes(); li++) {
370 node = side->node(li);
373 ((node->
getX() - side->centre()[ 0 ])*(node->
getX() - side->centre()[ 0 ])) +
374 ((node->
getY() - side->centre()[ 1 ])*(node->
getY() - side->centre()[ 1 ])) +
375 ((node->
getZ() - side->centre()[ 2 ])*(node->
getZ() - side->centre()[ 2 ]))
378 sum_side_dist[node_index] += dist;
379 sum_sides[node_index]++;
387 for (
unsigned int li = 0; li < ele->n_nodes(); li++) {
388 node = ele->node[li];
393 ((node->
getX() - ele->centre()[ 0 ])*(node->
getX() - ele->centre()[ 0 ])) +
394 ((node->
getY() - ele->centre()[ 1 ])*(node->
getY() - ele->centre()[ 1 ])) +
395 ((node->
getZ() - ele->centre()[ 2 ])*(node->
getZ() - ele->centre()[ 2 ]))
398 (1 - dist / (sum_ele_dist[node_index] + sum_side_dist[node_index])) /
399 (sum_elements[node_index] + sum_sides[node_index] - 1);
404 for (
unsigned int li = 0; li < side->n_nodes(); li++) {
405 node = side->node(li);
410 ((node->
getX() - side->centre()[ 0 ])*(node->
getX() - side->centre()[ 0 ])) +
411 ((node->
getY() - side->centre()[ 1 ])*(node->
getY() - side->centre()[ 1 ])) +
412 ((node->
getZ() - side->centre()[ 2 ])*(node->
getZ() - side->centre()[ 2 ]))
417 (1 - dist / (sum_ele_dist[node_index] + sum_side_dist[node_index])) /
418 (sum_sides[node_index] + sum_elements[node_index] - 1);
430 delete [] sum_elements;
432 delete [] sum_ele_dist;
433 delete [] sum_side_dist;
578 unsigned int wl = 2*(w-5)+7;
580 string bc_head_format =
"# %-*s%-*s%-*s%-*s%-*s%-*s\n",
581 bc_format =
"%*s%-*d%-*s %-*g%-*g%-*g%-*g\n",
582 bc_total_format =
"# %-*s%-*g%-*g%-*g\n\n\n";
583 s << setw((w*c+wl-15)/2) << setfill(
'-') <<
"-";
589 w,
"[total_balance]",w,
"[total_outflow]",w,
"[total_inflow]",w,
"[time]");
591 s.str(std::string());
592 s << setw(w*c+wl) << setfill(
'-') <<
"-";
598 double flux = dh.
side_flux( *(bcd->side()) );
602 if (! r.
is_valid())
xprintf(
Msg,
"Invalid region, ele % d, edg: % d\n", bcd->bc_ele_idx_, bcd->edge_idx_);
604 bcd_balance[bc_region_idx] += flux;
606 if (flux > 0) bcd_plus_balance[bc_region_idx] += flux;
607 else bcd_minus_balance[bc_region_idx] += flux;
612 double total_balance = 0,
615 for( RegionSet::const_iterator reg = b_set.begin(); reg != b_set.end(); ++reg) {
617 total_balance += bcd_balance[reg->boundary_idx()];
618 total_outflow += bcd_plus_balance[reg->boundary_idx()];
619 total_inflow += bcd_minus_balance[reg->boundary_idx()];
621 w, bcd_balance[reg->boundary_idx()], w, bcd_plus_balance[reg->boundary_idx()],
627 w,total_balance, w, total_outflow, w, total_inflow);
630 string src_head_format =
"# %-*s%-*s%-*s%-*s%-*s\n",
631 src_format =
"%*s%-*d%-*s %-*g%-*s%-*g\n",
632 src_total_format =
"# %-*s%-*g\n\n\n";
636 w,
"[total_balance]",2*w,
"",w,
"[time]");
644 src_balance[elm->element_accessor().region().bulk_idx()] += elm->measure() *
653 for( RegionSet::const_iterator reg = bulk_set.begin(); reg != bulk_set.end(); ++reg)
655 total_balance += src_balance[reg->bulk_idx()];
658 reg->label().c_str(), w, src_balance[reg->bulk_idx()],2*w,
"", w,
darcy_flow->
time().
t());
690 char dbl_fmt[ 16 ]=
"%.8g ";
692 xfprintf(
raw_output_file,
"// fields:\n//ele_id ele_presure flux_in_barycenter[3] n_sides side_pressures[n] side_fluxes[n]\n");
703 for (i = 0; i < 3; i++)
707 for (i = 0; i < ele->n_sides(); i++)
709 for (i = 0; i < ele->n_sides(); i++)
741 double pressure_error[2], velocity_error[2], div_error[2];
772 for (
unsigned int li = 0; li < ele->n_sides(); li++) {
773 fluxes[li] = result.
dh->
side_flux( *(ele->side( li ) ) );
774 pressure_traces[li] = result.
dh->
side_scalar( *(ele->side( li ) ) );
778 arma::vec analytical(5);
782 double velocity_diff=0, divergence_diff=0, pressure_diff=0, diff;
786 double mean_x_squared=0;
787 for(
unsigned int i_node=0; i_node < ele->n_nodes(); i_node++ )
788 for(
unsigned int j_node=0; j_node < ele->n_nodes(); j_node++ )
790 mean_x_squared += (i_node == j_node ? 2.0 : 1.0) / ( 6 * dim )
791 * arma::dot( ele->node[i_node]->point(), ele->node[j_node]->point());
794 for(
unsigned int i_point=0; i_point < fe_values.
n_points(); i_point++) {
798 analytical = anal_sol.
value(q_point, ele->element_accessor() );
799 for(
unsigned int i=0; i< 3; i++) anal_flux[i] = analytical[i+1];
803 for(
unsigned int i_shape=0; i_shape < ele->n_sides(); i_shape++) {
804 unsigned int oposite_node = (i_shape + dim) % (dim + 1);
806 diff += fluxes[ i_shape ] *
807 ( arma::dot( q_point, q_point )/ 2
809 - arma::dot( q_point, ele->node[oposite_node]->point() )
810 + arma::dot( ele->centre(), ele->node[oposite_node]->point() )
814 diff = - (1.0 / conductivity) * diff / dim / ele->measure() / cross + pressure_mean ;
815 diff = ( diff - analytical[0]);
816 pressure_diff += diff * diff * fe_values.
JxW(i_point);
820 flux_in_q_point.zeros();
821 for(
unsigned int i_shape=0; i_shape < ele->n_sides(); i_shape++) {
822 flux_in_q_point += fluxes[ i_shape ]
827 flux_in_q_point -= anal_flux;
828 velocity_diff += dot(flux_in_q_point, flux_in_q_point) * fe_values.
JxW(i_point);
832 for(
unsigned int i_shape=0; i_shape < ele->n_sides(); i_shape++) diff += fluxes[ i_shape ];
833 diff = ( diff / ele->measure() / cross - analytical[4]);
834 divergence_diff += diff * diff * fe_values.
JxW(i_point);
846 result.
div_error[dim-1] += divergence_diff;
856 DBGMSG(
"l2 norm output\n");
859 const unsigned int order = 4;
876 ExactSolution anal_sol_1d(5);
879 ExactSolution anal_sol_2d(5);
906 auto pressure_diff_ptr = std::make_shared< FieldElementwise<3, FieldValue<3>::Scalar> >(&(result.
pressure_diff[0]), 1,
mesh_->
n_elements());
908 auto div_diff_ptr = std::make_shared< FieldElementwise<3, FieldValue<3>::Scalar> >(&(result.
div_diff[0]), 1,
mesh_->
n_elements());
913 unsigned int solution_size;
922 switch (ele->dim()) {
925 l2_diff_local<1>( ele, fe_values_1d, anal_sol_1d, result);
928 l2_diff_local<2>( ele, fe_values_2d, anal_sol_2d, result);
933 os <<
"l2 norm output\n\n"
934 <<
"pressure error 1d: " << sqrt(result.
pressure_error[0]) << endl
935 <<
"pressure error 2d: " << sqrt(result.
pressure_error[1]) << endl
936 <<
"velocity error 1d: " << sqrt(result.
velocity_error[0]) << endl
937 <<
"velocity error 2d: " << sqrt(result.
velocity_error[1]) << endl
938 <<
"div error 1d: " << sqrt(result.
div_error[0]) << endl
939 <<
"div error 2d: " << sqrt(result.
div_error[1]);
void set_python_field_from_file(const FilePath &file_name, const string &func_name)
Field< 3, FieldValue< 3 >::VectorFixed > field_ele_flux
vector< double > ele_piezo_head
Class MappingP1 implements the affine transformation of the unit cell onto the actual cell...
Field< 3, FieldValue< 3 >::Scalar > velocity_diff
void set_limit_side(LimitSide side)
Declaration of class which handles the ordering of degrees of freedom (dof) and mappings between loca...
vector< double > div_diff
Output class for darcy_flow_mh model.
DarcyFlowMH_Steady * darcy_flow
#define FOR_ELEMENT_NODES(i, j)
virtual void get_solution_vector(double *&vec, unsigned int &vec_size)
const arma::vec::fixed< spacedim > point(const unsigned int point_no)
Return coordinates of the quadrature point in the actual cell system.
Header: The functions for all outputs.
static Input::Type::Record input_type
The specification of output stream.
unsigned int bulk_size() const
static Input::Type::Record input_type
Field< 3, FieldValue< 3 >::Scalar > field_node_pressure
#define FOR_ELEMENTS(_mesh_, __i)
int xfclose(FILE *stream)
FCLOSE WITH ERROR HANDLING.
DarcyFlowMHOutput(DarcyFlowMH_Steady *flow, Input::Record in_rec)
const double JxW(const unsigned int point_no)
Return the product of Jacobian determinant and the quadrature weight at given quadrature point...
int xfprintf(FILE *out, const char *fmt,...)
FPRINTF WITH ERROR HANDLING.
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.
void make_corner_scalar(vector< double > &node_scalar)
Class FEValues calculates finite element data on the actual cells such as shape function values...
bool is_current(const TimeMark::Type &mask) const
FieldPython< 3, FieldValue< 3 >::Vector > ExactSolution
void make_element_vector()
const RegionDB & region_db() const
const MH_DofHandler & get_mh_dofhandler()
Field< 3, FieldValue< 3 >::Integer > subdomain
I/O functions with filename storing, able to track current line in opened file. All standard stdio fu...
Partitioning * get_part()
static TimeMarks & marks()
FieldCommon & units(const string &units)
Set basic units of the field.
FiniteElement< dim, 3 > * fe() const
Symmetric Gauss-Legendre quadrature formulae on simplices.
const unsigned int n_points()
Returns the number of quadrature points.
DarcyFlowMH_Steady * darcy
unsigned int boundary_idx() const
Returns index of the region in the boundary set.
unsigned int size() const
Returns size of the container. This is independent of the allocated space.
Data for Darcy flow equation.
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 OutputTime * create_output_stream(const Input::Record &in_rec)
This method write all registered data to output streams.
OutputFields output_fields
double element_scalar(ElementFullIter &ele) const
temporary replacement for DofHandler accessor, scalar (pressure) on element
void update(ElementFullIter ele, FieldType &cond_anisothropy, FieldType_Scalar &cross_section, FieldType_Scalar &conductivity)
Definitions of basic Lagrangean finite elements with polynomial shape functions.
Field< 3, FieldValue< 3 >::TensorFixed > anisotropy
FILE * raw_output_file
Raw data output file.
#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
FILE * balance_output_file
Temporary solution for writing balance into separate file.
vector< double > ele_pressure
vector< double > velocity_diff
Input::Record in_rec_
Accessor to the input record for the DarcyFlow output.
vector< double > subdomains
void mark_output_times(const TimeGovernor &tg)
FieldSet fields_for_output
void output_internal_flow_data()
void set_time(const TimeGovernor &time)
static Input::Type::Selection output_selection
Dedicated class for storing path to input and output files.
vector< int > & seq_output_partition()
Field< 3, FieldValue< 3 >::Scalar > field_ele_piezo_head
Field< 3, FieldValue< 3 >::Scalar > conductivity
double side_flux(const Side &side) const
temporary replacement for DofHandler accessor, flux through given side
arma::vec3 RT0_value(ElementFullIter ele, arma::vec3 point, unsigned int face)
Field< 3, FieldValue< 3 >::Scalar > pressure_diff
OutputTime * output_stream
void output(OutputTime *stream)
unsigned int boundary_size() const
void get_dof_indices(const CellIterator &cell, unsigned int indices[]) const override
Returns the global indices of dofs associated to the cell.
void add_admissible_field_names(const Input::Array &in_array, const Input::Type::Selection &in_sel)
Registers names of output fields that can be written using this stream.
TimeGovernor const & time()
void set_field(const RegionSet &domain, FieldBasePtr field, double time=0.0)
void reinit(ElementFullIter &cell)
Update cell-dependent data (gradients, Jacobians etc.)
#define FOR_BOUNDARIES(_mesh_, i)
Mixed-hybrid of steady Darcy flow with sources and variable density.
Input::Type::Selection make_output_field_selection(const string &name, const string &desc="")
Definitions of particular quadrature rules on simplices.
FieldCommon & name(const string &name)
Calculates finite element data on the actual cell.
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)
Field< 3, FieldValue< 3 >::Scalar > cross_section
DarcyFlowMH_Steady::EqData * data_
bool is_valid() const
Returns false if the region has undefined/invalid value.
double side_scalar(const Side &side) const
temporary replacement for DofHandler accessor, scalar (pressure) on edge of the side ...
void l2_diff_local(ElementFullIter &ele, FEValues< dim, 3 > &fe_values, ExactSolution &anal_sol, DiffData &result)
vector< double > ele_flux
#define FOR_SIDES(_mesh_, it)
void make_node_scalar_param()
Calculate nodes scalar, store it in double* node_scalars instead of node->scalar. ...
const unsigned int n_global_dofs() const
Getter for the number of all mesh dofs required by the given finite element.
Field< 3, FieldValue< 3 >::Scalar > water_source_density
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm)
FieldCommon & output_type(OutputTime::DiscreteSpace rt)
vector< double > pressure_diff
void make_element_scalar()
NodeVector node_vector
Vector of nodes of the mesh.
FILE * xfopen(const std::string &fname, const char *mode)
void output()
Calculate values for output.
Transformed quadrature weights.