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.");
110 auto ele_pressure_ptr=make_shared< FieldElementwise<3, FieldValue<3>::Scalar> >(
ele_pressure, 1);
118 auto corner_ptr = make_shared< FieldFE<3, FieldValue<3>::Scalar> >();
126 make_shared< FieldElementwise<3, FieldValue<3>::Scalar> >(
ele_piezo_head, 1));
130 make_shared< FieldElementwise<3, FieldValue<3>::VectorFixed> >(
ele_flux, 3));
134 for(
unsigned int i=0; i<
subdomains.size();i++)
137 make_shared< FieldElementwise<3, FieldValue<3>::Integer> >(
subdomains, 1));
155 if (in_rec.
opt_val(
"raw_flow_output", raw_output_file_path)) {
156 xprintf(
Msg,
"Opening raw output: %s\n",
string(raw_output_file_path).c_str() );
215 unsigned int sol_size;
241 flux_in_centre.zeros();
248 for (
unsigned int li = 0; li < ele->n_sides(); li++) {
249 flux_in_centre += dh.
side_flux( *(ele->side( li ) ) )
250 * fe_values.
RT0_value( ele, ele->centre(), li )
254 for(
unsigned int j=0; j<3; j++)
255 ele_flux[3*i_side+j]=flux_in_centre[j];
265 unsigned int ndofs = max(
dh->
fe<1>()->n_dofs(), max(
dh->
fe<2>()->n_dofs(),
dh->
fe<3>()->n_dofs()));
266 unsigned int indices[ndofs];
305 int* sum_elements =
new int [n_nodes];
306 int* sum_sides =
new int [n_nodes];
307 double* sum_ele_dist =
new double [n_nodes];
308 double* sum_side_dist =
new double [n_nodes];
312 bool count_elements =
true;
313 bool count_sides =
true;
319 for (
int i = 0; i < n_nodes; i++){
322 sum_ele_dist[i] = 0.0;
323 sum_side_dist[i] = 0.0;
330 for (
unsigned int li = 0; li < ele->n_nodes(); li++) {
331 node = ele->node[li];
335 ((node->
getX() - ele->centre()[ 0 ])*(node->
getX() - ele->centre()[ 0 ])) +
336 ((node->
getY() - ele->centre()[ 1 ])*(node->
getY() - ele->centre()[ 1 ])) +
337 ((node->
getZ() - ele->centre()[ 2 ])*(node->
getZ() - ele->centre()[ 2 ]))
339 sum_ele_dist[node_index] += dist;
340 sum_elements[node_index]++;
345 for (
unsigned int li = 0; li < side->n_nodes(); li++) {
346 node = side->node(li);
349 ((node->
getX() - side->centre()[ 0 ])*(node->
getX() - side->centre()[ 0 ])) +
350 ((node->
getY() - side->centre()[ 1 ])*(node->
getY() - side->centre()[ 1 ])) +
351 ((node->
getZ() - side->centre()[ 2 ])*(node->
getZ() - side->centre()[ 2 ]))
354 sum_side_dist[node_index] += dist;
355 sum_sides[node_index]++;
363 for (
unsigned int li = 0; li < ele->n_nodes(); li++) {
364 node = ele->node[li];
369 ((node->
getX() - ele->centre()[ 0 ])*(node->
getX() - ele->centre()[ 0 ])) +
370 ((node->
getY() - ele->centre()[ 1 ])*(node->
getY() - ele->centre()[ 1 ])) +
371 ((node->
getZ() - ele->centre()[ 2 ])*(node->
getZ() - ele->centre()[ 2 ]))
374 (1 - dist / (sum_ele_dist[node_index] + sum_side_dist[node_index])) /
375 (sum_elements[node_index] + sum_sides[node_index] - 1);
380 for (
unsigned int li = 0; li < side->n_nodes(); li++) {
381 node = side->node(li);
386 ((node->
getX() - side->centre()[ 0 ])*(node->
getX() - side->centre()[ 0 ])) +
387 ((node->
getY() - side->centre()[ 1 ])*(node->
getY() - side->centre()[ 1 ])) +
388 ((node->
getZ() - side->centre()[ 2 ])*(node->
getZ() - side->centre()[ 2 ]))
393 (1 - dist / (sum_ele_dist[node_index] + sum_side_dist[node_index])) /
394 (sum_sides[node_index] + sum_elements[node_index] - 1);
400 delete [] sum_elements;
402 delete [] sum_ele_dist;
403 delete [] sum_side_dist;
427 unsigned int wl = 2*(w-5)+7;
429 string bc_head_format =
"# %-*s%-*s%-*s%-*s%-*s%-*s\n",
430 bc_format =
"%*s%-*d%-*s %-*g%-*g%-*g%-*g\n",
431 bc_total_format =
"# %-*s%-*g%-*g%-*g\n\n\n";
432 s << setw((w*c+wl-15)/2) << setfill(
'-') <<
"-";
438 w,
"[total_balance]",w,
"[total_outflow]",w,
"[total_inflow]",w,
"[time]");
440 s.str(std::string());
441 s << setw(w*c+wl) << setfill(
'-') <<
"-";
447 double flux = dh.
side_flux( *(bcd->side()) );
450 if (! r.
is_valid())
xprintf(
Msg,
"Invalid region, ele % d, edg: % d\n", bcd->bc_ele_idx_, bcd->edge_idx_);
452 bcd_balance[bc_region_idx] += flux;
454 if (flux > 0) bcd_plus_balance[bc_region_idx] += flux;
455 else bcd_minus_balance[bc_region_idx] += flux;
459 double total_balance = 0,
462 for( RegionSet::const_iterator reg = b_set.begin(); reg != b_set.end(); ++reg) {
463 total_balance += bcd_balance[reg->boundary_idx()];
464 total_outflow += bcd_plus_balance[reg->boundary_idx()];
465 total_inflow += bcd_minus_balance[reg->boundary_idx()];
467 w, bcd_balance[reg->boundary_idx()], w, bcd_plus_balance[reg->boundary_idx()],
473 w,total_balance, w, total_outflow, w, total_inflow);
476 string src_head_format =
"# %-*s%-*s%-*s%-*s%-*s\n",
477 src_format =
"%*s%-*d%-*s %-*g%-*s%-*g\n",
478 src_total_format =
"# %-*s%-*g\n\n\n";
482 w,
"[total_balance]",2*w,
"",w,
"[time]");
486 src_balance[elm->element_accessor().region().bulk_idx()] += elm->measure() *
494 for( RegionSet::const_iterator reg = bulk_set.begin(); reg != bulk_set.end(); ++reg)
496 total_balance += src_balance[reg->bulk_idx()];
499 reg->label().c_str(), w, src_balance[reg->bulk_idx()],2*w,
"", w,
darcy_flow->
time().
t());
517 char dbl_fmt[ 16 ]=
"%.8g ";
519 xfprintf(
raw_output_file,
"// fields:\n//ele_id ele_presure flux_in_barycenter[3] n_sides side_pressures[n] side_fluxes[n]\n");
529 for (i = 0; i < 3; i++)
533 for (i = 0; i < ele->n_sides(); i++)
535 for (i = 0; i < ele->n_sides(); i++)
562 double pressure_error[2], velocity_error[2], div_error[2];
591 for (
unsigned int li = 0; li < ele->n_sides(); li++) {
592 fluxes[li] = result.
dh->
side_flux( *(ele->side( li ) ) );
593 pressure_traces[li] = result.
dh->
side_scalar( *(ele->side( li ) ) );
597 arma::vec analytical(5);
601 double velocity_diff=0, divergence_diff=0, pressure_diff=0, diff;
605 double mean_x_squared=0;
606 for(
unsigned int i_node=0; i_node < ele->n_nodes(); i_node++ )
607 for(
unsigned int j_node=0; j_node < ele->n_nodes(); j_node++ )
609 mean_x_squared += (i_node == j_node ? 2.0 : 1.0) / ( 6 * dim )
610 * arma::dot( ele->node[i_node]->point(), ele->node[j_node]->point());
613 for(
unsigned int i_point=0; i_point < fe_values.
n_points(); i_point++) {
617 analytical = anal_sol.
value(q_point, ele->element_accessor() );
618 for(
unsigned int i=0; i< 3; i++) anal_flux[i] = analytical[i+1];
622 for(
unsigned int i_shape=0; i_shape < ele->n_sides(); i_shape++) {
623 unsigned int oposite_node = (i_shape + dim) % (dim + 1);
625 diff += fluxes[ i_shape ] *
626 ( arma::dot( q_point, q_point )/ 2
628 - arma::dot( q_point, ele->node[oposite_node]->point() )
629 + arma::dot( ele->centre(), ele->node[oposite_node]->point() )
633 diff = - (1.0 / conductivity) * diff / dim / ele->measure() / cross + pressure_mean ;
634 diff = ( diff - analytical[0]);
635 pressure_diff += diff * diff * fe_values.
JxW(i_point);
639 flux_in_q_point.zeros();
640 for(
unsigned int i_shape=0; i_shape < ele->n_sides(); i_shape++) {
641 flux_in_q_point += fluxes[ i_shape ]
646 flux_in_q_point -= anal_flux;
647 velocity_diff += dot(flux_in_q_point, flux_in_q_point) * fe_values.
JxW(i_point);
651 for(
unsigned int i_shape=0; i_shape < ele->n_sides(); i_shape++) diff += fluxes[ i_shape ];
652 diff = ( diff / ele->measure() / cross - analytical[4]);
653 divergence_diff += diff * diff * fe_values.
JxW(i_point);
665 result.
div_error[dim-1] += divergence_diff;
675 DBGMSG(
"l2 norm output\n");
678 const unsigned int order = 4;
695 ExactSolution anal_sol_1d(5);
698 ExactSolution anal_sol_2d(5);
718 auto pressure_diff_ptr = std::make_shared< FieldElementwise<3, FieldValue<3>::Scalar> >(&(result.
pressure_diff[0]), 1,
mesh_->
n_elements());
720 auto div_diff_ptr = std::make_shared< FieldElementwise<3, FieldValue<3>::Scalar> >(&(result.
div_diff[0]), 1,
mesh_->
n_elements());
725 unsigned int solution_size;
734 switch (ele->dim()) {
737 l2_diff_local<1>( ele, fe_values_1d, anal_sol_1d, result);
740 l2_diff_local<2>( ele, fe_values_2d, anal_sol_2d, result);
745 os <<
"l2 norm output\n\n"
746 <<
"pressure error 1d: " << sqrt(result.
pressure_error[0]) << endl
747 <<
"pressure error 2d: " << sqrt(result.
pressure_error[1]) << endl
748 <<
"velocity error 1d: " << sqrt(result.
velocity_error[0]) << endl
749 <<
"velocity error 2d: " << sqrt(result.
velocity_error[1]) << endl
750 <<
"div error 1d: " << sqrt(result.
div_error[0]) << endl
751 <<
"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...
FieldCommon & units(const UnitSI &units)
Set basic units of the field.
Partitioning * get_part()
static TimeMarks & marks()
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 ...
Class for representation SI units of Fields.
void l2_diff_local(ElementFullIter &ele, FEValues< dim, 3 > &fe_values, ExactSolution &anal_sol, DiffData &result)
vector< double > ele_flux
static UnitSI & dimensionless()
Returns dimensionless unit.
#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.