mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
improved output handling
This commit is contained in:
@ -226,18 +226,21 @@ void Foam::fieldAverage::read(const dictionary& dict)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::fieldAverage::write()
|
void Foam::fieldAverage::execute()
|
||||||
{
|
{
|
||||||
if (active_)
|
if (active_)
|
||||||
{
|
{
|
||||||
calcAverages();
|
calcAverages();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (obr_.time().outputTime())
|
|
||||||
{
|
|
||||||
writeAverages();
|
|
||||||
|
|
||||||
writeAveragingProperties();
|
void Foam::fieldAverage::write()
|
||||||
}
|
{
|
||||||
|
if (active_)
|
||||||
|
{
|
||||||
|
writeAverages();
|
||||||
|
writeAveragingProperties();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -279,6 +279,9 @@ public:
|
|||||||
//- Read the field average data
|
//- Read the field average data
|
||||||
virtual void read(const dictionary&);
|
virtual void read(const dictionary&);
|
||||||
|
|
||||||
|
//- Execute the averaging
|
||||||
|
virtual void execute();
|
||||||
|
|
||||||
//- Calculate the field average data and write
|
//- Calculate the field average data and write
|
||||||
virtual void write();
|
virtual void write();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -98,6 +98,12 @@ void Foam::forceCoeffs::writeFileHeader()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::forceCoeffs::execute()
|
||||||
|
{
|
||||||
|
// Do nothing - only valid on write
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::forceCoeffs::write()
|
void Foam::forceCoeffs::write()
|
||||||
{
|
{
|
||||||
if (active_)
|
if (active_)
|
||||||
|
|||||||
@ -126,7 +126,10 @@ public:
|
|||||||
//- Read the forces data
|
//- Read the forces data
|
||||||
virtual void read(const dictionary&);
|
virtual void read(const dictionary&);
|
||||||
|
|
||||||
//- Calculate the forces and write
|
//- Execute
|
||||||
|
virtual void execute();
|
||||||
|
|
||||||
|
//- Write the forces
|
||||||
virtual void write();
|
virtual void write();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -267,6 +267,11 @@ void Foam::forces::writeFileHeader()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::forces::execute()
|
||||||
|
{
|
||||||
|
// Do nothing - only valid on write
|
||||||
|
}
|
||||||
|
|
||||||
void Foam::forces::write()
|
void Foam::forces::write()
|
||||||
{
|
{
|
||||||
if (active_)
|
if (active_)
|
||||||
|
|||||||
@ -200,7 +200,10 @@ public:
|
|||||||
//- Read the forces data
|
//- Read the forces data
|
||||||
virtual void read(const dictionary&);
|
virtual void read(const dictionary&);
|
||||||
|
|
||||||
//- Calculate the forces and write
|
//- Execute
|
||||||
|
virtual void execute();
|
||||||
|
|
||||||
|
//- Write the forces
|
||||||
virtual void write();
|
virtual void write();
|
||||||
|
|
||||||
//- Calculate and return forces and moment
|
//- Calculate and return forces and moment
|
||||||
|
|||||||
@ -38,6 +38,8 @@ graphField/writePatchGraph.C
|
|||||||
graphField/writeCellGraph.C
|
graphField/writeCellGraph.C
|
||||||
graphField/makeGraph.C
|
graphField/makeGraph.C
|
||||||
|
|
||||||
|
outputFilters/outputFilterOutputControl/outputFilterOutputControl.C
|
||||||
|
|
||||||
meshToMesh = meshToMeshInterpolation/meshToMesh
|
meshToMesh = meshToMeshInterpolation/meshToMesh
|
||||||
$(meshToMesh)/meshToMesh.C
|
$(meshToMesh)/meshToMesh.C
|
||||||
$(meshToMesh)/calculateMeshToMeshAddressing.C
|
$(meshToMesh)/calculateMeshToMeshAddressing.C
|
||||||
|
|||||||
@ -49,7 +49,7 @@ namespace Foam
|
|||||||
class mapPolyMesh;
|
class mapPolyMesh;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class probes Declaration
|
Class IOOutputFilter Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
template<class OutputFilter>
|
template<class OutputFilter>
|
||||||
|
|||||||
@ -36,8 +36,7 @@ void Foam::OutputFilterFunctionObject<OutputFilter>::readDict()
|
|||||||
{
|
{
|
||||||
dict_.readIfPresent("region", regionName_);
|
dict_.readIfPresent("region", regionName_);
|
||||||
dict_.readIfPresent("dictionary", dictName_);
|
dict_.readIfPresent("dictionary", dictName_);
|
||||||
dict_.readIfPresent("interval", interval_);
|
dict_.readIfPresent("enabled", enabled_);
|
||||||
dict_.readIfPresent("enabled", execution_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -57,8 +56,8 @@ Foam::OutputFilterFunctionObject<OutputFilter>::OutputFilterFunctionObject
|
|||||||
dict_(dict),
|
dict_(dict),
|
||||||
regionName_(polyMesh::defaultRegion),
|
regionName_(polyMesh::defaultRegion),
|
||||||
dictName_(),
|
dictName_(),
|
||||||
interval_(0),
|
enabled_(true),
|
||||||
execution_(true)
|
outputControl_(t, dict)
|
||||||
{
|
{
|
||||||
readDict();
|
readDict();
|
||||||
}
|
}
|
||||||
@ -71,7 +70,7 @@ bool Foam::OutputFilterFunctionObject<OutputFilter>::start()
|
|||||||
{
|
{
|
||||||
readDict();
|
readDict();
|
||||||
|
|
||||||
if (execution_)
|
if (enabled_)
|
||||||
{
|
{
|
||||||
if (dictName_.size())
|
if (dictName_.size())
|
||||||
{
|
{
|
||||||
@ -105,9 +104,14 @@ bool Foam::OutputFilterFunctionObject<OutputFilter>::start()
|
|||||||
template<class OutputFilter>
|
template<class OutputFilter>
|
||||||
bool Foam::OutputFilterFunctionObject<OutputFilter>::execute()
|
bool Foam::OutputFilterFunctionObject<OutputFilter>::execute()
|
||||||
{
|
{
|
||||||
if (execution_ && (interval_ <= 1 || !(time_.timeIndex() % interval_)) )
|
if (enabled_)
|
||||||
{
|
{
|
||||||
ptr_->write();
|
ptr_->execute();
|
||||||
|
|
||||||
|
if (enabled_ && outputControl_.output())
|
||||||
|
{
|
||||||
|
ptr_->write();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -117,14 +121,14 @@ bool Foam::OutputFilterFunctionObject<OutputFilter>::execute()
|
|||||||
template<class OutputFilter>
|
template<class OutputFilter>
|
||||||
void Foam::OutputFilterFunctionObject<OutputFilter>::on()
|
void Foam::OutputFilterFunctionObject<OutputFilter>::on()
|
||||||
{
|
{
|
||||||
execution_ = true;
|
enabled_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class OutputFilter>
|
template<class OutputFilter>
|
||||||
void Foam::OutputFilterFunctionObject<OutputFilter>::off()
|
void Foam::OutputFilterFunctionObject<OutputFilter>::off()
|
||||||
{
|
{
|
||||||
execution_ = false;
|
enabled_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -137,6 +141,8 @@ bool Foam::OutputFilterFunctionObject<OutputFilter>::read
|
|||||||
if (dict != dict_)
|
if (dict != dict_)
|
||||||
{
|
{
|
||||||
dict_ = dict;
|
dict_ = dict;
|
||||||
|
outputControl_.read(dict);
|
||||||
|
|
||||||
return start();
|
return start();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@ -45,6 +45,7 @@ SourceFiles
|
|||||||
|
|
||||||
#include "functionObject.H"
|
#include "functionObject.H"
|
||||||
#include "dictionary.H"
|
#include "dictionary.H"
|
||||||
|
#include "outputFilterOutputControl.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -68,12 +69,10 @@ class OutputFilterFunctionObject
|
|||||||
word regionName_;
|
word regionName_;
|
||||||
word dictName_;
|
word dictName_;
|
||||||
|
|
||||||
//- the execution interval (in time steps)
|
|
||||||
// a value <= 1 means execute at every time step
|
|
||||||
label interval_;
|
|
||||||
|
|
||||||
//- Switch for the execution of the functionObjects
|
//- Switch for the execution of the functionObjects
|
||||||
bool execution_;
|
bool enabled_;
|
||||||
|
|
||||||
|
outputFilterOutputControl outputControl_;
|
||||||
|
|
||||||
autoPtr<OutputFilter> ptr_;
|
autoPtr<OutputFilter> ptr_;
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,119 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "outputFilterOutputControl.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<>
|
||||||
|
const char* Foam::NamedEnum
|
||||||
|
<
|
||||||
|
Foam::outputFilterOutputControl::outputControls,
|
||||||
|
2
|
||||||
|
>::names[] =
|
||||||
|
{
|
||||||
|
"timeStep",
|
||||||
|
"outputTime"
|
||||||
|
};
|
||||||
|
|
||||||
|
const Foam::NamedEnum<Foam::outputFilterOutputControl::outputControls, 2>
|
||||||
|
Foam::outputFilterOutputControl::outputControlNames_;
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::outputFilterOutputControl::outputFilterOutputControl
|
||||||
|
(
|
||||||
|
const Time& time,
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
time_(time),
|
||||||
|
outputControl_(ocTimeStep),
|
||||||
|
outputInterval_(0)
|
||||||
|
{
|
||||||
|
read(dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::outputFilterOutputControl::~outputFilterOutputControl()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::outputFilterOutputControl::read(const dictionary& dict)
|
||||||
|
{
|
||||||
|
outputControl_ = outputControlNames_.read(dict.lookup("outputControl"));
|
||||||
|
|
||||||
|
switch (outputControl_)
|
||||||
|
{
|
||||||
|
case ocTimeStep:
|
||||||
|
{
|
||||||
|
dict.lookup("outputInterval") >> outputInterval_;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::outputFilterOutputControl::output() const
|
||||||
|
{
|
||||||
|
switch (outputControl_)
|
||||||
|
{
|
||||||
|
case ocTimeStep:
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(
|
||||||
|
!(time_.timeIndex() % outputInterval_)
|
||||||
|
|| (outputInterval_ <= 1)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ocOutputTime:
|
||||||
|
{
|
||||||
|
return time_.outputTime();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
FatalErrorIn("bool Foam::outputFilterOutputControl::output()")
|
||||||
|
<< "Unknown output control: "
|
||||||
|
<< outputControlNames_[outputControl_] << nl
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,127 @@
|
|||||||
|
/*---------------------------------------------------------------------------* \
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::outputFilterOutputControl
|
||||||
|
|
||||||
|
Description
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
outputFilterOutputControl.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef outputFilterOutputControl_H
|
||||||
|
#define outputFilterOutputControl_H
|
||||||
|
|
||||||
|
#include "dictionary.H"
|
||||||
|
#include "Time.H"
|
||||||
|
#include "NamedEnum.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class outputFilterOutputControl Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class outputFilterOutputControl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum outputControls
|
||||||
|
{
|
||||||
|
ocTimeStep,
|
||||||
|
ocOutputTime
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
//- Time object
|
||||||
|
const Time& time_;
|
||||||
|
|
||||||
|
//- String representation of outputControls enums
|
||||||
|
static const NamedEnum<outputControls, 2> outputControlNames_;
|
||||||
|
|
||||||
|
//- Type of output
|
||||||
|
outputControls outputControl_;
|
||||||
|
|
||||||
|
//- The execution interval (in time steps) when using TIMESTEP mode
|
||||||
|
// a value <= 1 means execute at every time step
|
||||||
|
label outputInterval_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct and assignment
|
||||||
|
outputFilterOutputControl(const outputFilterOutputControl&);
|
||||||
|
void operator=(const outputFilterOutputControl&);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from dictionary and Time object
|
||||||
|
outputFilterOutputControl
|
||||||
|
(
|
||||||
|
const Time& time,
|
||||||
|
const dictionary& dict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
~outputFilterOutputControl();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Read from dictionary
|
||||||
|
void read(const dictionary& dict);
|
||||||
|
|
||||||
|
//- Return const access to the Time object
|
||||||
|
const Time& time() const
|
||||||
|
{
|
||||||
|
return time_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Flag to indicate whether to output
|
||||||
|
bool output() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -298,6 +298,12 @@ Foam::probes::~probes()
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::probes::execute()
|
||||||
|
{
|
||||||
|
// Do nothing - only valid on write
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::probes::write()
|
void Foam::probes::write()
|
||||||
{
|
{
|
||||||
if (probeLocations_.size() && checkFieldTypes())
|
if (probeLocations_.size() && checkFieldTypes())
|
||||||
|
|||||||
@ -200,6 +200,9 @@ public:
|
|||||||
//- Read the probes
|
//- Read the probes
|
||||||
virtual void read(const dictionary&);
|
virtual void read(const dictionary&);
|
||||||
|
|
||||||
|
//- Execute
|
||||||
|
virtual void execute();
|
||||||
|
|
||||||
//- Update for changes of mesh
|
//- Update for changes of mesh
|
||||||
virtual void updateMesh(const mapPolyMesh&)
|
virtual void updateMesh(const mapPolyMesh&)
|
||||||
{}
|
{}
|
||||||
|
|||||||
@ -269,6 +269,12 @@ void Foam::sampledSets::verbose(const bool verbosity)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void::Foam::sampledSets::execute()
|
||||||
|
{
|
||||||
|
// Do nothing - only valid on write
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::sampledSets::write()
|
void Foam::sampledSets::write()
|
||||||
{
|
{
|
||||||
if (size() && checkFieldTypes())
|
if (size() && checkFieldTypes())
|
||||||
|
|||||||
@ -278,6 +278,9 @@ public:
|
|||||||
//- set verbosity level
|
//- set verbosity level
|
||||||
void verbose(const bool verbosity = true);
|
void verbose(const bool verbosity = true);
|
||||||
|
|
||||||
|
//- Execute
|
||||||
|
virtual void execute();
|
||||||
|
|
||||||
//- Sample and write
|
//- Sample and write
|
||||||
virtual void write();
|
virtual void write();
|
||||||
|
|
||||||
|
|||||||
@ -309,6 +309,12 @@ void Foam::sampledSurfaces::verbose(const bool verbosity)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void::Foam::sampledSurfaces::execute()
|
||||||
|
{
|
||||||
|
// Do nothing - only valid on write
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::sampledSurfaces::write()
|
void Foam::sampledSurfaces::write()
|
||||||
{
|
{
|
||||||
if (size() && checkFieldTypes())
|
if (size() && checkFieldTypes())
|
||||||
|
|||||||
@ -86,7 +86,8 @@ class sampledSurfaces
|
|||||||
formatter(surfaceWriter<Type>::New(writeFormat))
|
formatter(surfaceWriter<Type>::New(writeFormat))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//- Construct for a particular surface format and a list of field names
|
//- Construct for a particular surface format and a list of field
|
||||||
|
// names
|
||||||
fieldGroup
|
fieldGroup
|
||||||
(
|
(
|
||||||
const word& writeFormat,
|
const word& writeFormat,
|
||||||
@ -250,6 +251,9 @@ public:
|
|||||||
//- set verbosity level
|
//- set verbosity level
|
||||||
void verbose(const bool verbosity = true);
|
void verbose(const bool verbosity = true);
|
||||||
|
|
||||||
|
//- Execute
|
||||||
|
virtual void execute();
|
||||||
|
|
||||||
//- Sample and write
|
//- Sample and write
|
||||||
virtual void write();
|
virtual void write();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user