49 #define LEPLIC_ZERO_VOF 1.e-8 50 #define LEPLIC_BRENT_EPS 1.e-8 61 if ( ( fvi > 0. ) && ( fvi <= 1.0 ) ) {
63 if ( ( fvi > 0. ) && ( fvi < 1.0 ) ) {
70 for (
int ineighbr: neighborList ) {
71 if ( ( ineghbrInterface =
117 if ( !stream.
read(
p) ) {
142 this->doLagrangianPhase(tStep);
143 this->doInterfaceReconstruction(tStep,
true,
false);
148 this->doInterfaceRemapping(tStep);
151 this->doInterfaceReconstruction(tStep,
false,
true);
153 ESIEventLoop( NO, const_cast< char * >(
"doInterfaceReconstruction Finished; Press Ctrl-p to continue") );
162 int i, ci, ndofman = domain->giveNumberOfDofManagers();
174 velocityMask = {V_u, V_v};
176 updated_XCoords.
resize(ndofman);
177 updated_YCoords.resize(ndofman);
180 for ( i = 1; i <= ndofman; i++ ) {
181 dman = domain->giveDofManager(i);
182 inode =
dynamic_cast< Node *
>(dman);
200 for ( ci = 1; ci <= nsd; ci++ ) {
201 x2.at(ci) = x.
at(ci) + 0.5 *dt *v_t.
at(ci);
208 if ( vfield == NULL ) {
212 err = vfield->evaluateAt(v_tn1, x2, VM_Total, tStep);
216 }
else if ( err != 0 ) {
217 OOFEM_ERROR(
"vfield->evaluateAt failed, error code %d", err);
221 for ( ci = 1; ci <= nsd; ci++ ) {
222 x2.at(ci) = x.
at(ci) + dt *v_tn1.
at(ci);
229 for ( ci = 1; ci <= nsd; ci++ ) {
230 x2.at(ci) = x.
at(ci) + dt *v_t.
at(ci);
235 updated_XCoords.at(i) = x2.at(1);
236 updated_YCoords.at(i) = x2.at(2);
245 int nelem = domain->giveNumberOfElements();
253 for (
int ie = 1; ie <= nelem; ie++ ) {
255 this->doCellDLS(fvgrad, ie, coord_upd, temp_vof);
257 this->findCellLineConstant(p, fvgrad, ie, coord_upd, temp_vof);
273 int neighbrNum, nelem = domain->giveNumberOfElements();
274 double in_vof, total_volume = 0.0, in_vol;
280 double matVol = 0.0, matVolSum = 0.0;
284 for (
int ie = 1; ie <= nelem; ie++ ) {
285 if ( ( interface = static_cast< LEPlicElementInterface * >( domain->giveElement(ie)->giveInterface(
LEPlicElementInterfaceType) ) ) ) {
291 for (
int ie = 1; ie <= nelem; ie++ ) {
296 domain->giveConnectivityTable()->giveElementNeighbourList(neighbours, elNum);
298 if ( ( interface = static_cast< LEPlicElementInterface * >( domain->giveElement(ie)->giveInterface(
LEPlicElementInterfaceType) ) ) ) {
316 for (
int in = 1; in <= neighbours.
giveSize(); in++ ) {
317 neighbrNum = neighbours.
at(in);
318 if ( ( neghbrInterface = static_cast< LEPlicElementInterface * >
322 total_volume += in_vol;
329 neighbrNum = neighbours.
at(1);
330 if ( ( neghbrInterface = static_cast< LEPlicElementInterface * >
340 double err = fabs(matVol - matVolSum) / matVol;
341 if ( ( err > 1.e-12 ) && ( fabs(matVol - matVolSum) > 1.e-4 ) && ( matVol > 1.e-6 ) ) {
346 if ( ( err > 2.e-3 ) && ( fabs(matVol - matVolSum) > 2.e-3 ) ) {
362 for (
int in = 1; in <= neighbours.
giveSize(); in++ ) {
363 neighbrNum = neighbours.
at(in);
364 if ( neghbrInterface = static_cast< LEPlicElementInterface * >
368 total_volume += in_vol;
375 for (
int in = 1; in <= neighbours.
giveSize(); in++ ) {
376 neighbrNum = neighbours.
at(in);
377 if ( neghbrInterface = static_cast< LEPlicElementInterface * >
381 total_volume += in_vol;
388 for (
int in = 1; in <= neighbours.
giveSize(); in++ ) {
389 neighbrNum = neighbours.
at(in);
390 if ( neghbrInterface = static_cast< LEPlicElementInterface * >
394 total_volume += in_vol;
409 OOFEM_ERROR(
"Element with no LEPlicInterface support encountered");
414 for (
int ie = 1; ie <= nelem; ie++ ) {
415 if ( ( interface = static_cast< LEPlicElementInterface * >( domain->giveElement(ie)->giveInterface(
LEPlicElementInterfaceType) ) ) ) {
426 OOFEM_LOG_INFO(
"LEPlic::doInterfaceRemapping: Total volume is %e", total_volume);
427 if ( orig_reference_fluid_volume > 0.0 ) {
428 OOFEM_LOG_INFO(
"LEPlic::doInterfaceRemapping: Volume error is %5.2f%%\n",
429 ( ( total_volume - orig_reference_fluid_volume ) / orig_reference_fluid_volume ) * 100.0);
443 double fvi, fvk, wk, dx, dy;
444 bool isBoundaryCell =
false;
451 if ( ( interface = static_cast< LEPlicElementInterface * >( domain->giveElement(ie)->giveInterface(
LEPlicElementInterfaceType) ) ) ) {
452 if ( vof_temp_flag ) {
458 if ( ( fvi > 0. ) && ( fvi <= 1.0 ) ) {
461 if ( ( fvi > 0. ) && ( fvi < 1.0 ) ) {
462 isBoundaryCell =
true;
479 for (
int ineighbr: neighborList ) {
480 if ( ineighbr == ie ) {
484 if ( ( ineghbrInterface =
486 if ( vof_temp_flag ) {
493 isBoundaryCell =
true;
498 dx = ( xk.
at(1) - xi.at(1) ) / wk;
499 dy = ( xk.
at(2) - xi.at(2) ) / wk;
500 lhs.
at(1, 1) += dx * dx;
501 lhs.
at(1, 2) += dx * dy;
502 lhs.
at(2, 2) += dy * dy;
504 rhs.at(1) += ( fvi - fvk ) * dx / wk;
505 rhs.at(2) += ( fvi - fvk ) * dy / wk;
509 if ( isBoundaryCell ) {
511 lhs.
at(2, 1) = lhs.
at(1, 2);
552 Element *elem = domain->giveElement(ie);
556 double ivx, ivy, pp, target_vof;
557 if ( temp_vof_flag ) {
558 target_vof = interface->giveTempVolumeFraction();
560 target_vof = interface->giveVolumeFraction();
571 double upper_vof = 10.0, lower_vof = -10.0;
572 double upper_p = 0.0, lower_p = 0.0;
574 if ( temp_vof_flag ) {
575 fvi = interface->giveTempVolumeFraction();
577 fvi = interface->giveVolumeFraction();
584 for (
int ivert = 1; ivert <= nelemnodes; ivert++ ) {
594 pp = -( fvgrad.
at(1) * ivx + fvgrad.
at(2) * ivy );
595 ivof = interface->computeLEPLICVolumeFraction(fvgrad, pp,
this, coord_upd);
596 if ( ( ( ivof - target_vof ) >= 0. ) && ( ivof < upper_vof ) ) {
599 }
else if ( ( ( target_vof - ivof ) >= 0. ) && ( ivof > lower_vof ) ) {
605 if ( ( lower_vof >= 0. ) && ( upper_vof <= 1.00000000001 ) ) {
607 brent(lower_p, 0.5 * ( lower_p + upper_p ), upper_p,
639 OOFEM_ERROR(
"finding lower and uper bounds of line constant value failed (lowerVOF = %lf, upperVOF=%lf)", lower_vof, upper_vof);
649 orig_reference_fluid_volume = 0.0;
668 for (
auto &elem : domain->giveElements() ) {
681 Element *elem = domain->giveSpatialLocalizer()->giveElementContainingPoint(position);
686 interface->giveTempInterfaceNormal(n);
687 interface->formVolumeInterfacePoly(pg,
this, n, interface->giveTempLineConstant(),
false);
705 Element *elem = domain->giveElement(ie);
708 answer.
at(1) = interface->giveTempVolumeFraction();
709 answer.
at(2) = 1. - answer.
at(1);
719 bool vof_1 =
false, vof_0 =
false;
720 double vof, vofsum = 0.0;
721 const IntArray *shelem = domain->giveConnectivityTable()->giveDofManConnectivityArray(inode);
723 for (
int i = 1; i <= shelem->
giveSize(); i++ ) {
729 }
else if ( vof == 1.0 ) {
737 if ( vof_0 && vof_1 ) {
739 }
else if ( vof_0 ) {
741 }
else if ( vof_1 ) {
contextIOResultType saveContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Stores context of receiver into given stream.
Element interface for LEPlic class representing Lagrangian-Eulerian (moving) material interface...
std::shared_ptr< Field > FieldPtr
void doInterfaceReconstruction(TimeStep *tStep, bool coord_upd, bool temp_vof)
bool solveForRhs(const FloatArray &b, FloatArray &answer, bool transpose=false)
Solves the system of linear equations .
double computeVolume() const
virtual Element * giveElement()=0
Return number of receiver's element.
The purpose of DataStream abstract class is to allow to store/restore context to different streams...
contextIOResultType storeYourself(DataStream &stream) const
void addTempVolumeFraction(double v)
double & at(int i)
Coefficient access function.
void doCellDLS(FloatArray &fvgrad, int ie, bool coord_upd, bool temp_vof_flag)
virtual double computeCriticalLEPlicTimeStep(TimeStep *tStep)=0
Computes critical time step.
ConnectivityTable * giveConnectivityTable()
Returns receiver's associated connectivity table.
oofem::oofegGraphicContext gc[OOFEG_LAST_LAYER]
void setTempInterfaceNormal(FloatArray tg)
Abstract base class for all finite elements.
void giveTempInterfaceNormal(FloatArray &n)
Base class for dof managers.
virtual double giveCoordinate(int i)
FieldManager * giveFieldManager()
Class implementing an array of integers.
int & at(int i)
Coefficient access function.
virtual int read(int *data, int count)=0
Reads count integer values into array pointed by data.
#define _IFT_LEPLIC_refVol
double giveTimeIncrement()
Returns solution step associated time increment.
virtual int giveNumberOfNodes() const
Returns number of nodes of receiver.
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
double distance(const FloatArray &x) const
Computes the distance between position represented by receiver and position given as parameter...
virtual int write(const int *data, int count)=0
Writes count integer values from array pointed by data.
void giveUnknownVector(FloatArray &answer, const IntArray &dofMask, ValueModeType mode, TimeStep *tStep, bool padding=false)
Assembles the vector of unknowns in global c.s for given dofs of receiver.
#define OOFEM_LOG_INFO(...)
int giveNumber()
Returns receiver's number.
Element * giveElement(int n)
Service for accessing particular domain fe element.
EngngModelContext * giveContext()
Context requesting service.
double brent(double ax, double bx, double cx, const T &f, double tol, double &xmin)
virtual void giveMaterialMixtureAt(FloatArray &answer, FloatArray &position)
Returns relative material contents at given point.
double giveTempLineConstant()
contextIOResultType restoreYourself(DataStream &stream)
Class representing connectivity table.
virtual void giveElementCenter(LEPlic *mat_interface, FloatArray ¢er, bool updFlag)=0
Computes the receiver center (in updated Lagrangian configuration).
Class representing the special graph constructed from two polygons that is used to perform boolean op...
TimeStep * givePreviousStep()
Returns pointer to previous solution step.
double at(int i, int j) const
Coefficient access function.
void resize(int n)
Checks size of receiver towards requested bounds.
void giveElementNeighbourList(IntArray &answer, IntArray &elemList)
Returns list of neighboring elements to given elements (they are included too).
FieldPtr giveField(FieldType key)
Returns the previously registered field under given key; NULL otherwise.
void findCellLineConstant(double &p, FloatArray &fvgrad, int ie, bool coord_upd, bool temp_vof_flag)
virtual void updatePosition(TimeStep *tStep)
Updates the position of interface according to state reached in given solution step.
void EVFastRedraw(EView *v_p)
Class representing vector of real numbers.
Class representing 2D polygon.
Implementation of matrix containing floating point numbers.
double giveTempVolumeFraction()
IRResultType
Type defining the return values of InputRecord reading operations.
void doLagrangianPhase(TimeStep *tStep)
void setTempLineConstant(double tp)
void setTempVolumeFraction(double v)
double giveVolumeFraction()
virtual void giveElementMaterialMixture(FloatArray &answer, int ielem)
Returns volumetric (or other based measure) of relative material contents in given element...
virtual double truncateMatVolume(const Polygon &matvolpoly, double &volume)=0
Truncates given material polygon to receiver.
virtual double giveNodalScalarRepresentation(int)
Returns scalar value representation of material Interface at given point.
void zero()
Zeroes all coefficients of receiver.
virtual Interface * giveInterface(InterfaceType t)
Interface requesting service.
long ContextMode
Context mode (mask), defining the type of information written/read to/from context.
contextIOResultType restoreContext(DataStream &stream, ContextMode mode, void *obj=NULL)
Restores context of receiver from given stream.
void deleteLayerGraphics(int iLayer)
double vof
Volume fraction of reference fluid in element.
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
virtual FloatArray * giveCoordinates()
void zero()
Zeroes all coefficient of receiver.
Domain * giveDomain() const
int min(int i, int j)
Returns smaller value from two given decimals.
virtual void formMaterialVolumePoly(Polygon &matvolpoly, LEPlic *matInterface, const FloatArray &normal, const double p, bool updFlag)=0
Assembles the true element material polygon (takes receiver vof into accout).
#define OOFEG_DEBUG_LAYER
int testPoint(double x, double y) const
double p
Line constant of line segment representing interface.
Abstract base class representing the "problem" under consideration.
GraphicObj * draw(oofegGraphicContext &, bool filled, int layer=OOFEG_DEBUG_LAYER)
the oofem namespace is to define a context or scope in which all oofem names are defined.
void doInterfaceRemapping(TimeStep *tStep)
Class implementing node in finite element mesh.
void negated()
Switches the sign of every coefficient of receiver.
double normalize()
Normalizes receiver.
Node * giveNode(int i) const
Returns reference to the i-th node of element.
#define OOFEM_WARNING(...)
FloatArray normal
Interface segment normal.
EngngModel * giveEngngModel()
Returns reference to itself -> required by communicator.h.
Class representing solution step.
virtual double computeCriticalTimeStep(TimeStep *tStep)
Computes critical time step induced by receiver integration algorithm.
bool isBoundary()
Returns true if cell is boundary.
void resize(int s)
Resizes receiver towards requested size.