103 vec [ i ] += m(i, i) * u [ i ];
176PFEM :: forceEquationNumbering(
int id)
195 for (
Dof *jDof: *dman ) {
197 if ( ( type == V_u ) || ( type == V_v ) || ( type == V_w ) ) {
198 jDof->askNewEquationNumber(currStep);
204 pns.init(domain, currStep);
215 EngngModel :: initializeFrom(ir);
260 if ( mode == VM_Intermediate ) {
262 int index =
avns.giveDofEquationNumber(dof);
263 if ( index > 0 && index <=
AuxVelocity.giveSize() ) {
277 OOFEM_ERROR(
"giveUnknown: Dof unknowns dictionary does not contain unknown of value mode (%s)", __ValueModeTypeToString(mode) );
288PFEM :: giveSolutionStepWhenIcApply(
bool force)
290 if (
master && (!force)) {
291 return master->giveSolutionStepWhenIcApply();
301PFEM :: preInitializeNextStep()
316 element->checkConsistency();
318 for (
int j = 1; j <= element->giveNumberOfDofManagers(); j++ ) {
327 for (
Dof *jDof: *dman ) {
329 if ( ( type == V_u ) || ( type == V_v ) || ( type == V_w ) ) {
330 if ( jDof->giveBcId() ) {
340PFEM :: giveNextStep()
343 double totalTime = 0;
352 counter =
currentStep->giveSolutionStateCounter() + 1;
357 EngngModel :: forceEquationNumbering();
377 currentStep = std::make_unique<TimeStep>(istep,
this, 1, totalTime, ndt, counter);
400 double d_pnorm = 1.0;
401 double d_vnorm = 1.0;
406 avLhs.resize(auxmomneq);
412 OOFEM_ERROR(
"solveYourselfAt: sparse matrix creation failed");
415 pLhs->buildInternalStructure(
this, 1,
pns);
444 FloatArray velocityVectorThisStep(* velocityVector);
445 FloatArray velocityVectorLastStep(* velocityVector);
447 FloatArray pressureVectorThisStep(* pressureVector);
448 FloatArray pressureVectorLastStep(* pressureVector);
451 for (
int i = 1; i <= this->
giveDomain(1)->giveNumberOfDofManagers(); i++ ) {
457 externalForces.
resize(auxmomneq);
464 velocityVectorLastStep = velocityVectorThisStep;
465 pressureVectorLastStep = pressureVectorThisStep;
473 if ( iteration > 1 ) {
483 rhs.
add(externalForces);
499 for (
int i = 1; i <= auxmomneq; i++ ) {
511 pressureVector->
resize(presneq);
514 for (
auto &dman : this->
giveDomain(1)->giveDofManagers() ) {
524 velocityVector->
resize(momneq);
531 for (
int i = 1; i <= momneq; i++ ) {
532 velocityVector->
at(i) = rhs.
at(i) /
vLhs.at(i);
535 for (
int i = 1; i <= this->
giveDomain(1)->giveNumberOfDofManagers(); i++ ) {
540 velocityVectorThisStep = * velocityVector;
541 pressureVectorThisStep = * pressureVector;
543 if ( iteration == 1 ) {
547 FloatArray diffVelocity = velocityVectorThisStep;
548 diffVelocity.
subtract(velocityVectorLastStep);
551 for (
int i = 1; i <= diffVelocity.
giveSize(); i++ ) {
552 d_vnorm =
max(d_vnorm, fabs( diffVelocity.
at(i) ) > 1.e-6 ? fabs( diffVelocity.
at(i) / velocityVectorLastStep.
at(i) ) : 0);
555 FloatArray diffPressure = pressureVectorThisStep;
556 diffPressure.
subtract(pressureVectorLastStep);
558 for (
int i = 1; i <= diffPressure.
giveSize(); i++ ) {
560 d_pnorm =
max(d_pnorm, fabs( diffPressure.
at(i) ) > 1.e-6 ? fabs( diffPressure.
at(i) / pressureVectorLastStep.
at(i) ) : 0);
578 for (
Dof *dof : *particle ) {
580 if ( type == V_u || type == V_v || type == V_w ) {
581 int eqnum = dof->giveEquationNumber(
vns);
583 double previousValue = dof->giveUnknown( VM_Total, tStep->
givePreviousStep() );
587 previousValue += gVector [ type - V_w ] *
deltaT;
588 velocityVector->
at(eqnum) = previousValue;
602 EngngModel :: updateYourself(stepN);
614 for (
auto &dman : domain->giveDofManagers() ) {
619 for (
auto &elem : domain->giveElements() ) {
620 elem->updateInternalState(stepN);
626PFEM :: giveUnknownDictHashIndx(ValueModeType mode,
TimeStep *stepN)
629 int index = ( stepN->
giveNumber() % 2 ) * 100 + mode;
632 OOFEM_ERROR(
"giveUnknownDictHashIndx: unsupported solution step");
641 for (
Dof *iDof: *inode ) {
644 if ( iDof->hasBc(tStep) ) {
645 val = iDof->giveBcValue(VM_Total, tStep);
647 if ( iDof->giveDofID() == P_f ) {
648 eqNum =
pns.giveDofEquationNumber(iDof);
651 val = vect->
at(eqNum);
654 eqNum = iDof->__giveEquationNumber();
657 val = vect->
at(eqNum);
662 iDof->updateUnknownsDictionary(tStep, VM_Total, val);
671 if ( iDof->
hasBc(tStep) ) {
674 int eqNum =
pns.giveDofEquationNumber(iDof);
676 val = vect->
at(eqNum);
685 for (
Dof *iDof : *inode ) {
687 if ( type == V_u || type == V_v || type == V_w ) {
690 if ( iDof->hasBc(tStep) ) {
691 val = iDof->giveBcValue(VM_Total, tStep);
693 eqNum = iDof->__giveEquationNumber();
696 val = vect->
at(eqNum);
699 iDof->updateUnknownsDictionary(tStep, VM_Total, val);
709 EngngModel :: saveContext(stream, mode);
719 EngngModel :: restoreContext(stream, mode);
726PFEM :: checkConsistency()
732 if ( !
dynamic_cast< PFEMElement *
>( elem.get() ) ) {
733 OOFEM_WARNING(
"Element %d has no PFEM base", elem->giveLabel() );
738 return EngngModel :: checkConsistency();
743PFEM :: printDofOutputAt(FILE *stream,
Dof *iDof,
TimeStep *atTime)
746 if ( ( type == V_u ) || ( type == V_v ) || ( type == V_w ) ) {
752 double coordinate = 0.0;
755 case V_u: dofNumber = 1;
757 case V_v: dofNumber = 2;
759 case V_w: dofNumber = 3;
764 fprintf(stream,
" dof %d c % .8e\n", dofNumber, coordinate);
765 }
else if ( ( type == P_f ) ) {
768 OOFEM_ERROR(
"printDofOutputAt: unsupported dof type");
784 int velocityFieldStepNumber =
VelocityField.giveActualStepNumber();
786 if ( velocityFieldStepNumber < stepWhenIcApply->giveNumber() ) {
790 velocityVector->
resize(mbneq);
791 velocityVector->
zero();
793 int pressureFieldStepNumber =
PressureField.giveActualStepNumber();
794 if ( pressureFieldStepNumber < stepWhenIcApply->giveNumber() ) {
798 pressureVector->
resize(pdneq);
799 pressureVector->
zero();
803 for (
Dof *iDof: *node ) {
807 if ( !iDof->isPrimaryDof() ) {
811 int jj = iDof->__giveEquationNumber();
815 if ( ( type == V_u ) || ( type == V_v ) || ( type == V_w ) ) {
836 if ( (
id == V_u ) || (
id == V_v ) || (
id == V_w ) ) {
837 return this->
vns.askNewEquationNumber();
839 OOFEM_ERROR(
"giveNewEquationNumber:: Unknown DofIDItem");
846PFEM :: giveNewPrescribedEquationNumber(
int domain,
DofIDItem id)
848 if ( (
id == V_u ) || (
id == V_v ) || (
id == V_w ) ) {
851 OOFEM_ERROR(
"giveNewPrescribedEquationNumber:: Unknown DofIDItem");
865 EngngModel :: forceEquationNumbering();
873PFEM :: resetEquationNumberings()
882PFEM :: deactivateTooCloseParticles()
898 double maxLength =
max( l12,
max(l23, l31) );
899 double minLength =
min( l12,
min(l23, l31) );
902 if ( fabs(l12 - minLength) < 1.e-6 ) {
904 bool isSupported =
false;
906 for (
Dof *jDof: *particle1 ) {
908 if ( ( type == V_u ) || ( type == V_v ) || ( type == V_w ) ) {
909 if ( jDof->giveBcId() ) {
914 if ( isSupported ==
false ) {
915 particle1->deactivate();
919 }
else if ( particle1->
isActive() ==
false || particle2->
isActive() ==
false ) {
926 if ( fabs(l23 - minLength) < 1.e-6 ) {
928 bool isSupported =
false;
930 for (
Dof *jDof : *particle2 ) {
932 if ( ( type == V_u ) || ( type == V_v ) || ( type == V_w ) ) {
933 if ( jDof->giveBcId() ) {
938 if ( isSupported ==
false ) {
939 particle2->deactivate();
943 }
else if ( particle2->
isActive() ==
false || particle3->
isActive() ==
false ) {
950 if ( fabs(l31 - minLength) < 1.e-6 ) {
952 bool isSupported =
false;
953 for (
Dof *jDof : *particle3 ) {
955 if ( ( type == V_u ) || ( type == V_v ) || ( type == V_w ) ) {
956 if ( jDof->giveBcId() ) {
961 if ( isSupported ==
false ) {
962 particle3->deactivate();
966 }
else if ( particle3->
isActive() ==
false || particle1->
isActive() ==
false ) {
#define REGISTER_EngngModel(class)
void generateMesh()
Main call.
double giveCoordinate(int i) const
const FloatArray & giveCoordinates() const
Dof * giveDofWithID(int dofID) const
DofIDItem giveDofID() const
virtual double giveBcValue(ValueModeType mode, TimeStep *tStep)
virtual void updateUnknownsDictionary(TimeStep *tStep, ValueModeType mode, double dofValue)
virtual void giveUnknowns(FloatArray &masterUnknowns, ValueModeType mode, TimeStep *tStep)
DofManager * giveDofManager() const
virtual void printSingleOutputAt(FILE *file, TimeStep *tStep, char ch, ValueModeType mode, double scale=1.0)
virtual bool hasBc(TimeStep *tStep)=0
void clearElements()
Clear all elements.
int giveNumberOfElements() const
Returns number of elements in domain.
std ::vector< std ::unique_ptr< DofManager > > & giveDofManagers()
Element * giveElement(int n)
std ::vector< std ::unique_ptr< Element > > & giveElements()
Node * giveNode(int i) const
virtual double computeArea()
virtual void updateYourself(TimeStep *tStep)
void giveLocationArray(IntArray &locationArray, const UnknownNumberingScheme &s, IntArray *dofIds=NULL) const
void computeVectorOf(ValueModeType u, TimeStep *tStep, FloatArray &answer)
int giveNumberOfTimeStepWhenIcApply()
Returns the time step number, when initial conditions should apply.
std ::vector< std ::unique_ptr< Domain > > domainList
List of problem domains.
virtual TimeStep * giveCurrentStep(bool force=false)
void assembleVectorFromElements(FloatArray &answer, TimeStep *tStep, const VectorAssembler &va, ValueModeType mode, const UnknownNumberingScheme &s, Domain *domain, FloatArray *eNorms=NULL)
std ::unique_ptr< TimeStep > previousStep
Previous time step.
int equationNumberingCompleted
Equation numbering completed flag.
Domain * giveDomain(int n)
std ::unique_ptr< TimeStep > currentStep
Current time step.
MetaStep * giveMetaStep(int i)
Returns the i-th meta step.
virtual double giveVariableScale(VarScaleType varId)
Returns the scale factor for given variable type.
virtual TimeStep * givePreviousStep(bool force=false)
EngngModel * master
Master e-model; if defined receiver is in maintained (slave) mode.
virtual int giveNumberOfFirstStep(bool force=false)
std ::unique_ptr< TimeStep > stepWhenIcApply
Solution step when IC (initial conditions) apply.
IntArray domainPrescribedNeqs
Number of prescribed equations per domain.
void assembleVector(FloatArray &answer, TimeStep *tStep, const VectorAssembler &va, ValueModeType mode, const UnknownNumberingScheme &s, Domain *domain, FloatArray *eNorms=NULL)
IntArray domainNeqs
Number of equations per domain.
void computeVectorOfPressures(ValueModeType mode, TimeStep *tStep, FloatArray &pressures)
void computeVectorOfVelocities(ValueModeType mode, TimeStep *tStep, FloatArray &velocities)
double computeNorm() const
void assemble(const FloatArray &fe, const IntArray &loc)
Index giveSize() const
Returns the size of receiver.
void zero()
Zeroes all coefficients of receiver.
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
void add(const FloatArray &src)
void subtract(const FloatArray &src)
int giveNumberOfColumns() const
Returns number of columns of receiver.
virtual void computeComponentArrayAt(FloatArray &answer, TimeStep *tStep, ValueModeType mode)
virtual double computeCriticalTimeStep(TimeStep *tStep)=0
Calculates critical time step.
virtual void computePrescribedRhsVector(FloatArray &answer, TimeStep *tStep, ValueModeType mode)=0
Calculates the prescribed velocity vector for the right hand side of the pressure equation.
void giveCharacteristicMatrix(FloatMatrix &answer, CharType, TimeStep *) override
virtual void computeStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, TimeStep *atTime)=0
Calculates the stiffness matrix.
virtual const IntArray & givePressureDofMask() const =0
Returns mask of pressure Dofs.
virtual void computeDiagonalMassMtrx(FloatArray &answer, TimeStep *)=0
virtual void computePressureLaplacianMatrix(FloatMatrix &answer, TimeStep *atTime)=0
Calculates the pressure laplacian matrix.
void updateInternalState(TimeStep *tStep) override
virtual void computeGradientMatrix(FloatMatrix &answer, TimeStep *atTime)=0
Calculates the pressure gradient matrix.
virtual void setFree(bool newFlag=true)
Sets the free-property flag.
virtual void deactivate()
Sets the activeFlag to false.
virtual bool isActive()
Returns the activeFlag.
virtual bool isFree()
Returns the free-propery flag.
std ::unique_ptr< SparseLinearSystemNM > nMethod
Numerical method used to solve the problem.
FloatArray AuxVelocity
Array of auxiliary velocities used during computation.
void applyIC(TimeStep *)
Initializes velocity and pressure fields in the first step with prescribed values.
void updateInternalState(TimeStep *)
void updateDofUnknownsDictionaryVelocities(DofManager *inode, TimeStep *tStep)
Writes velocities into the dof unknown dictionaries.
int giveUnknownDictHashIndx(ValueModeType mode, TimeStep *stepN) override
int maxiter
Max number of iterations.
bool printVolumeReport
Flag for volume report.
LinSystSolverType solverType
Used solver type for linear system of equations.
void updateDofUnknownsDictionaryPressure(DofManager *inode, TimeStep *tStep)
Writes pressures into the dof unknown dictionaries.
double domainVolume
Area or volume of the fluid domain, which can be controlled.
AuxVelocityNumberingScheme avns
Auxiliary Velocity numbering.
int associatedCrossSection
Number of cross section to associate with created elements.
PressureNumberingScheme pns
Pressure numbering.
double deltaT
Time step length.
SparseMtrxType sparseMtrxType
Used type of sparse matrix.
FloatArray avLhs
Left-hand side matrix for the auxiliary velocity equations.
double rtolv
Convergence tolerance.
void deactivateTooCloseParticles()
Deactivates particles upon the particalRemovalRatio.
TimeStep * giveSolutionStepWhenIcApply(bool force=false) override
VelocityNumberingScheme vns
Velocity numbering.
PrimaryField VelocityField
Velocity field.
int discretizationScheme
Explicit or implicit time discretization.
std ::unique_ptr< SparseMtrx > pLhs
Left-hand side matrix for the pressure equations.
FloatArray vLhs
Left-hand side matrix for the velocity equations.
int associatedMaterial
Number of material to associate with created elements.
double minDeltaT
Minimal value of time step.
int associatedPressureBC
Number of pressure boundary condition to be prescribed on free surface.
int giveNumberOfDomainEquations(int, const UnknownNumberingScheme &num) override
PrimaryField PressureField
Pressure field.
double alphaShapeCoef
Value of alpha coefficient for the boundary recognition.
void updateDofUnknownsDictionary(DofManager *inode, TimeStep *tStep) override
NumericalMethod * giveNumericalMethod(MetaStep *) override
Returns reference to receiver's numerical method.
int requiresUnknownsDictionaryUpdate() override
double particleRemovalRatio
Element side ratio for the removal of the close partices.
void resetEquationNumberings()
Resets the equation numberings as the mesh is recreated in each time step.
VelocityNumberingScheme prescribedVns
Prescribed velocity numbering.
double computeCriticalTimeStep(TimeStep *tStep) override
Calculates critical time step.
int giveMetaStepNumber()
Returns receiver's meta step number.
void incrementStateCounter()
Updates solution state counter.
double giveTimeIncrement()
Returns solution step associated time increment.
int giveNumber()
Returns receiver's number.
TimeStep * givePreviousStep()
Returns pointer to previous solution step.
virtual int giveRequiredNumberOfDomainEquation() const
#define _IFT_EngngModel_lstype
#define _IFT_EngngModel_smtype
#define OOFEM_WARNING(...)
#define OOFEM_LOG_INFO(...)
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
FloatArrayF< N > assemble(const FloatArrayF< M > &x, int const (&c)[M])
Assemble components into zero matrix.
long StateCounterType
StateCounterType type used to indicate solution state.
FloatArrayF< N > max(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
ClassFactory & classFactory
double distance(const FloatArray &x, const FloatArray &y)
#define _IFT_PFEM_discretizationScheme
#define _IFT_PFEM_mindeltat
#define _IFT_PFEM_maxiter
#define _IFT_PFEM_printVolumeReport
#define _IFT_PFEM_associatedCrossSection
#define _IFT_PFEM_associatedMaterial
#define _IFT_PFEM_particalRemovalRatio
#define _IFT_PFEM_alphashapecoef
#define _IFT_PFEM_pressureBC
#define VERBOSE_PRINTS(str, str1)