49#define LEPLIC_ZERO_VOF 1.e-8
50#define LEPLIC_BRENT_EPS 1.e-8
54LEPlicElementInterface :: isBoundary()
61 if ( ( fvi > 0. ) && ( fvi <= 1.0 ) ) {
63 if ( ( fvi > 0. ) && ( fvi < 1.0 ) ) {
70 for (
int ineighbr: neighborList ) {
71 if ( ( ineghbrInterface =
98 if ( ( iores =
normal.storeYourself(stream) ) !=
CIO_OK ) {
113 if ( !stream.
read(
p) ) {
118 if ( ( iores =
normal.restoreYourself(stream) ) !=
CIO_OK ) {
146 ESIEventLoop( NO,
const_cast< char *
>(
"doInterfaceReconstruction Finished; Press Ctrl-p to continue") );
155 int ci, ndofman =
domain->giveNumberOfDofManagers();
165 velocityMask = {V_u, V_v};
171 for (
int i = 1; i <= ndofman; i++ ) {
173 Node *inode =
dynamic_cast< Node *
>(dman);
191 for ( ci = 1; ci <= nsd; ci++ ) {
192 x2.at(ci) = x.at(ci) + 0.5 *dt *v_t.
at(ci);
202 err = vfield->evaluateAt(v_tn1, x2, VM_Total, tStep);
206 }
else if ( err != 0 ) {
207 OOFEM_ERROR(
"vfield->evaluateAt failed, error code %d", err);
211 for ( ci = 1; ci <= nsd; ci++ ) {
212 x2.at(ci) = x.at(ci) + dt * v_tn1.
at(ci);
219 for ( ci = 1; ci <= nsd; ci++ ) {
220 x2.at(ci) = x.at(ci) + dt *v_t.
at(ci);
231LEPlic :: doInterfaceReconstruction(
TimeStep *tStep,
bool coord_upd,
bool temp_vof)
235 int nelem =
domain->giveNumberOfElements();
243 for (
int ie = 1; ie <= nelem; ie++ ) {
245 this->
doCellDLS(fvgrad, ie, coord_upd, temp_vof);
263 int neighbrNum, nelem =
domain->giveNumberOfElements();
264 double in_vof, total_volume = 0.0, in_vol;
270 double matVol = 0.0, matVolSum = 0.0;
274 for (
int ie = 1; ie <= nelem; ie++ ) {
281 for (
int ie = 1; ie <= nelem; ie++ ) {
286 domain->giveConnectivityTable()->giveElementNeighbourList(neighbours, elNum);
306 for (
int in = 1; in <= neighbours.
giveSize(); in++ ) {
307 neighbrNum = neighbours.
at(in);
312 total_volume += in_vol;
319 neighbrNum = neighbours.
at(1);
330 double err = fabs(matVol - matVolSum) / matVol;
331 if ( ( err > 1.e-12 ) && ( fabs(matVol - matVolSum) > 1.e-4 ) && ( matVol > 1.e-6 ) ) {
336 if ( ( err > 2.e-3 ) && ( fabs(matVol - matVolSum) > 2.e-3 ) ) {
352 for (
int in = 1; in <= neighbours.
giveSize(); in++ ) {
353 neighbrNum = neighbours.
at(in);
358 total_volume += in_vol;
365 for (
int in = 1; in <= neighbours.
giveSize(); in++ ) {
366 neighbrNum = neighbours.
at(in);
371 total_volume += in_vol;
378 for (
int in = 1; in <= neighbours.
giveSize(); in++ ) {
379 neighbrNum = neighbours.
at(in);
384 total_volume += in_vol;
399 OOFEM_ERROR(
"Element with no LEPlicInterface support encountered");
404 for (
int ie = 1; ie <= nelem; ie++ ) {
416 OOFEM_LOG_INFO(
"LEPlic::doInterfaceRemapping: Total volume is %e", total_volume);
418 OOFEM_LOG_INFO(
"LEPlic::doInterfaceRemapping: Volume error is %5.2f%%\n",
431LEPlic :: doCellDLS(
FloatArray &fvgrad,
int ie,
bool coord_upd,
bool vof_temp_flag)
433 double fvi, fvk, wk, dx, dy;
434 bool isBoundaryCell =
false;
442 if ( vof_temp_flag ) {
448 if ( ( fvi > 0. ) && ( fvi <= 1.0 ) ) {
451 if ( ( fvi > 0. ) && ( fvi < 1.0 ) ) {
452 isBoundaryCell =
true;
469 for (
int ineighbr: neighborList ) {
470 if ( ineighbr == ie ) {
474 if ( ( ineghbrInterface =
476 if ( vof_temp_flag ) {
483 isBoundaryCell =
true;
488 dx = ( xk.
at(1) - xi.at(1) ) / wk;
489 dy = ( xk.
at(2) - xi.at(2) ) / wk;
490 lhs.
at(1, 1) += dx * dx;
491 lhs.
at(1, 2) += dx * dy;
492 lhs.
at(2, 2) += dy * dy;
494 rhs.at(1) += ( fvi - fvk ) * dx / wk;
495 rhs.at(2) += ( fvi - fvk ) * dy / wk;
499 if ( isBoundaryCell ) {
501 lhs.
at(2, 1) = lhs.
at(1, 2);
533LEPlic :: findCellLineConstant(
double &p,
FloatArray &fvgrad,
int ie,
bool coord_upd,
bool temp_vof_flag)
546 double ivx, ivy, pp, target_vof;
547 if ( temp_vof_flag ) {
548 target_vof = interface->giveTempVolumeFraction();
550 target_vof = interface->giveVolumeFraction();
561 double upper_vof = 10.0, lower_vof = -10.0;
562 double upper_p = 0.0, lower_p = 0.0;
564 if ( temp_vof_flag ) {
565 fvi = interface->giveTempVolumeFraction();
567 fvi = interface->giveVolumeFraction();
574 for (
int ivert = 1; ivert <= nelemnodes; ivert++ ) {
584 pp = -( fvgrad.
at(1) * ivx + fvgrad.
at(2) * ivy );
585 ivof = interface->computeLEPLICVolumeFraction(fvgrad, pp,
this, coord_upd);
586 if ( ( ( ivof - target_vof ) >= 0. ) && ( ivof < upper_vof ) ) {
589 }
else if ( ( ( target_vof - ivof ) >= 0. ) && ( ivof > lower_vof ) ) {
595 if ( ( lower_vof >= 0. ) && ( upper_vof <= 1.00000000001 ) ) {
597 brent(lower_p, 0.5 * ( lower_p + upper_p ), upper_p,
629 OOFEM_ERROR(
"finding lower and uper bounds of line constant value failed (lowerVOF = %lf, upperVOF=%lf)", lower_vof, upper_vof);
655 for (
auto &elem :
domain->giveElements() ) {
668 Element *elem =
domain->giveSpatialLocalizer()->giveElementContainingPoint(position);
673 interface->giveTempInterfaceNormal(n);
674 interface->formVolumeInterfacePoly(pg,
this, n, interface->giveTempLineConstant(),
false);
689LEPlic :: giveElementMaterialMixture(
FloatArray &answer,
int ie)
695 answer.
at(1) = interface->giveTempVolumeFraction();
696 answer.
at(2) = 1. - answer.
at(1);
704LEPlic :: giveNodalScalarRepresentation(
int inode)
706 bool vof_1 =
false, vof_0 =
false;
707 double vof, vofsum = 0.0;
708 const IntArray *shelem =
domain->giveConnectivityTable()->giveDofManConnectivityArray(inode);
710 for (
int i = 1; i <= shelem->
giveSize(); i++ ) {
713 vof = interface->giveTempVolumeFraction();
716 }
else if ( vof == 1.0 ) {
724 if ( vof_0 && vof_1 ) {
726 }
else if ( vof_0 ) {
728 }
else if ( vof_1 ) {
void giveElementNeighbourList(IntArray &answer, const IntArray &elemList)
virtual int read(int *data, std::size_t count)=0
Reads count integer values into array pointed by data.
virtual int write(const int *data, std::size_t count)=0
Writes count integer values from array pointed by data.
double giveCoordinate(int i) const
const FloatArray & giveCoordinates() const
void giveUnknownVector(FloatArray &answer, const IntArray &dofMask, ValueModeType mode, TimeStep *tStep, bool padding=false)
ConnectivityTable * giveConnectivityTable()
Element * giveElement(int n)
Node * giveNode(int i) const
virtual int giveNumberOfNodes() const
FieldManager * giveFieldManager()
EngngModelContext * giveContext()
Context requesting service.
virtual Interface * giveInterface(InterfaceType t)
Domain * domain
Link to domain object, useful for communicating with other FEM components.
FieldPtr giveField(FieldType key)
void zero()
Zeroes all coefficients of receiver.
void zero()
Zeroes all coefficient of receiver.
double at(std::size_t i, std::size_t j) const
bool solveForRhs(const FloatArray &b, FloatArray &answer, bool transpose=false)
virtual Element * giveElement()=0
Return number of receiver's element.
double giveVolumeFraction()
FloatArray normal
Interface segment normal.
void setTempLineConstant(double tp)
void addTempVolumeFraction(double v)
virtual double computeCriticalLEPlicTimeStep(TimeStep *tStep)=0
Computes critical time step.
double p
Line constant of line segment representing interface.
double giveTempLineConstant()
void setTempInterfaceNormal(FloatArray tg)
double giveTempVolumeFraction()
virtual double truncateMatVolume(const Polygon &matvolpoly, double &volume)=0
Truncates given material polygon to receiver.
void giveTempInterfaceNormal(FloatArray &n)
void setTempVolumeFraction(double v)
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).
double vof
Volume fraction of reference fluid in element.
virtual void giveElementCenter(LEPlic *mat_interface, FloatArray ¢er, bool updFlag)=0
Computes the receiver center (in updated Lagrangian configuration).
void doInterfaceReconstruction(TimeStep *tStep, bool coord_upd, bool temp_vof)
double orig_reference_fluid_volume
double giveUpdatedXCoordinate(int num)
void doInterfaceRemapping(TimeStep *tStep)
void findCellLineConstant(double &p, FloatArray &fvgrad, int ie, bool coord_upd, bool temp_vof_flag)
void doLagrangianPhase(TimeStep *tStep)
FloatArray updated_YCoords
Array used to store updated y-coordinates of nodes as moved along streamlines.
void doCellDLS(FloatArray &fvgrad, int ie, bool coord_upd, bool temp_vof_flag)
double giveUpdatedYCoordinate(int num)
FloatArray updated_XCoords
Array used to store updated x-coordinates of nodes as moved along streamlines.
GraphicObj * draw(oofegGraphicContext &, bool filled, int layer=OOFEG_DEBUG_LAYER)
double computeVolume() const
int testPoint(double x, double y) const
double giveTimeIncrement()
Returns solution step associated time increment.
int giveNumber()
Returns receiver's number.
TimeStep * givePreviousStep()
Returns pointer to previous solution step.
#define OOFEM_WARNING(...)
#define _IFT_LEPLIC_refVol
#define OOFEM_LOG_INFO(...)
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
@ LEPlicElementInterfaceType
std::shared_ptr< Field > FieldPtr
double distance(const FloatArray &x, const FloatArray &y)
@ CIO_IOERR
General IO error.
double brent(double ax, double bx, double cx, const T &f, double tol, double &xmin)
void EVFastRedraw(EView *v_p)
oofem::oofegGraphicContext gc[OOFEG_LAST_LAYER]
#define OOFEG_DEBUG_LAYER
void deleteLayerGraphics(int iLayer)