73WeakPeriodicBoundaryCondition :: ~WeakPeriodicBoundaryCondition()
78WeakPeriodicBoundaryCondition :: initializeFrom(
InputRecord &ir)
80 ActiveBoundaryCondition :: initializeFrom(ir);
110 for (
int i = 0; i < temp.
giveSize() / 2; i++ ) {
111 side [ 0 ].push_back( temp.
at(2 * i + 1) );
112 element [ 0 ].push_back( temp.
at(2 * i + 2) );
118 for (
int i = 0; i < temp.
giveSize() / 2; i++ ) {
119 side [ 1 ].push_back( temp.
at(2 * i + 1) );
120 element [ 1 ].push_back( temp.
at(2 * i + 2) );
126void WeakPeriodicBoundaryCondition :: postInitialize()
128 ActiveBoundaryCondition :: postInitialize();
130 g.resize(this->
domain->giveNumberOfSpatialDimensions());
134 if ( this->
domain->giveNumberOfSpatialDimensions() == 2 ) {
137 }
else if ( this->
domain->giveNumberOfSpatialDimensions() == 3 ) {
149 for (
int i = 0; i <
ndof; i++ ) {
150 int dofid = this->
domain->giveNextFreeDofID();
155void WeakPeriodicBoundaryCondition :: computeOrthogonalBasis()
162 for (
int i = 2; i <=
ndof; i++ ) {
166 for (
int j = 1; j < i; j++ ) {
170 for (
int k = 1; k <=
ndof; uTemp.
at(k) =
gsMatrix.at(j, k), k++ ) {
175 uTemp.
times(-thisValue);
185double WeakPeriodicBoundaryCondition :: computeProjectionCoefficient(
int vIndex,
int uIndex)
190 double value = 0.0, nom = 0.0, denom = 0.0;
196 thisOrder = thisOrder + A + B;
199 for (
size_t ielement = 0; ielement <
element [ thisSide ].size(); ielement++ ) {
209 const FloatArray &lcoords = gp->giveNaturalCoordinates();
220 for (
int k = 1; k <
ndof; k++ ) {
226 nom = nom + vVal *uValue *detJ *gp->giveWeight();
227 denom = denom + uValue *uValue *detJ *gp->giveWeight();
240 if ( this->
domain->giveNumberOfSpatialDimensions() == 3 ) {
255void WeakPeriodicBoundaryCondition :: updateDirection()
260 if ( this->
domain->giveNumberOfSpatialDimensions() == 2 ) {
272 if ( fabs( normal.
at(1) ) > 0.99999 ) {
274 if ( this->
domain->giveNumberOfSpatialDimensions() == 2 ) {
280 }
else if ( fabs( normal.
at(2) ) > 0.99999 ) {
282 if ( this->
domain->giveNumberOfSpatialDimensions() == 2 ) {
288 }
else if ( fabs( normal.
at(3) ) > 0.99 ) {
290 if ( this->
domain->giveNumberOfSpatialDimensions() == 2 ) {
291 OOFEM_ERROR(
"3 dimensioal normal in a 2 dimensional problem.");
299 OOFEM_ERROR(
"Only surfaces with normal in x, y or z direction supported. (el=%d, side=%d) \n", thisElement->
giveLabel(),
side [ 0 ].at(0) );
303void WeakPeriodicBoundaryCondition :: updateSminmax()
311 for (
int i = 0; i < posBoundary.
giveSize() / 2; i++ ) {
312 side [ 0 ].push_back( posBoundary.
at(2 * i + 2) );
313 element [ 0 ].push_back( posBoundary.
at(2 * i + 1) );
317 for (
int i = 0; i < negBoundary.
giveSize() / 2; i++ ) {
318 side [ 1 ].push_back( negBoundary.
at(2 * i + 2) );
319 element [ 1 ].push_back( negBoundary.
at(2 * i + 1) );
327 double normalSum = -1;
328 ( this->
giveDomain()->giveNumberOfSpatialDimensions() <= 2 ) ? normalSum = normal.
at(1) + normal.
at(2) : normalSum = normal.
at(1) + normal.
at(2) + normal.
at(3);
330 if ( normalSum > -0.000001 ) {
344 for (
int j = 1; j <= this->
domain->giveNumberOfDofManagers(); j++ ) {
346 smin.at(i) = std :: min(
smin.at(i), sValue);
347 smax.at(i) = std :: max(
smax.at(i), sValue);
358void WeakPeriodicBoundaryCondition :: addElementSide(
int newElement,
int newSide)
364 if (
element [ 0 ].size() > 0 ) {
368 double d = sqrt( pow(normalNew.
at(1) - normal0.
at(1), 2) + pow(normalNew.
at(2) - normal0.
at(2), 2) );
369 if ( fabs(d) < 0.001 ) {
377 if ( fabs(fabs( normalNew.
at(1) ) - 1.) < 0.0001 ) {
384 element [ addToList ].push_back(newElement);
385 side [ addToList ].push_back(newSide);
407 BH.
at(1, 3 * i - 2) = dNdx.
at(i, 1);
408 BH.
at(2, 3 * i - 1) = dNdx.
at(i, 2);
409 BH.
at(3, 3 * i - 0) = dNdx.
at(i, 3);
410 BH.
at(4, 3 * i - 1) = dNdx.
at(i, 3);
411 BH.
at(7, 3 * i - 0) = dNdx.
at(i, 2);
412 BH.
at(5, 3 * i - 2) = dNdx.
at(i, 3);
413 BH.
at(8, 3 * i - 0) = dNdx.
at(i, 1);
414 BH.
at(6, 3 * i - 2) = dNdx.
at(i, 2);
415 BH.
at(9, 3 * i - 1) = dNdx.
at(i, 1);
450 const FloatArray &lcoords = gp->giveNaturalCoordinates();
481 B(k, j) +=
N(k) * fVal * detJ * gp->giveWeight();
490 if ( type != TangentStiffnessMatrix && type != StiffnessMatrix ) {
504 for (
int thisSide = 0; thisSide <= 1; thisSide++ ) {
507 for (
size_t ielement = 0; ielement <
element [ thisSide ].size(); ielement++ ) {
509 int boundary =
side [ thisSide ].at(ielement);
528 for (
auto &gp: *iRule ) {
529 auto const &lcoords = gp->giveNaturalCoordinates();
540 for (
int i=0; i<
tcount; i++) {
541 for (
int j=0; j<
ndofids; j++) {
546 for (
int i=0; i<
N.giveSize(); i++) {
547 for (
int j=0; j<
ndofids; j++) {
548 Mv.at(j+1,
ndofids*i+j+1) =
N.at(i+1);
568 NvTNbeta.
times(J * detJ * gp->giveWeight());
587 omp_set_lock(
static_cast<omp_lock_t*
>(lock));
589 answer.
assemble(r_sideLoc, c_loc, B);
590 answer.
assemble(r_loc, c_sideLoc, BT);
593 omp_unset_lock(
static_cast<omp_lock_t*
>(lock));
601WeakPeriodicBoundaryCondition :: computeBaseFunctionValue(
int baseID,
FloatArray coordinate)
603 if (this->
domain->giveNumberOfSpatialDimensions() == 2) {
610double WeakPeriodicBoundaryCondition :: computeBaseFunctionValue2D(
int baseID,
FloatArray coordinate)
617 fVal = pow(coordinate.
at(1), a) * pow(coordinate.
at(2), b);
619 for (
int i = 1; i <=
ndof; i++ ) {
622 fVal = fVal +
gsMatrix.at(baseID+1, i) * pow(coordinate.
at(1), a) * pow(coordinate.
at(2), b);
629double WeakPeriodicBoundaryCondition :: computeBaseFunctionValue1D(
int baseID,
double coordinate)
636 for (
int i = 1; i <=
smax.giveSize(); i++ ) {
641 fVal = pow(coordinate, baseID);
643 if ( baseID % 2 == 0 ) {
644 fVal = cos( ( (
double ) baseID ) / 2. * ( coordinate * 2. *
M_PI / sideLength.
at(1) ) );
646 fVal = sin( ( (
double ) baseID + 1 ) / 2. * ( coordinate * 2. *
M_PI / sideLength.
at(1) ) );
649 double n = ( double ) baseID;
650 coordinate = 2.0 * coordinate - 1.0;
651 for (
int k = 0; k <= baseID; k++ ) {
652 fVal = fVal +
binomial(n, k) *
binomial(-n - 1.0, k) * pow( ( 1.0 - coordinate ) / 2.0, (
double ) k );
663 if ( type == InternalForcesVector ) {
665 }
else if ( type == ExternalForcesVector ) {
685 IntArray sideLocation, masterDofIDs;
694 for (
int thisSide = 0; thisSide <= 1; thisSide++ ) {
697 for (
size_t ielement = 0; ielement <
element [ thisSide ].size(); ielement++ ) {
699 int boundary =
side [ thisSide ].at(ielement);
729 FloatArray lcoords = gp->giveNaturalCoordinates();
739 for (
int i=0; i<
tcount; i++) {
741 for (
int j=0; j<
ndofids; j++) {
748 for (
int i=0; i<
ndofids; i++) {
749 for (
int j=0; j<
N.giveSize(); j++) {
772 gammaProd.
plusProduct(D, a, J*detJ*gp->giveWeight()*normalSign);
773 vProd.
plusProduct(C, gamma, J*detJ*gp->giveWeight()*normalSign);
791 if (lock) omp_set_lock(
static_cast<omp_lock_t*
>(lock));
798 answer.
assemble(gammaProd, gammaLoc);
799 answer.
assemble(vProd, sideLocation);
801 if (lock) omp_unset_lock(
static_cast<omp_lock_t*
>(lock));
826 for (
int thisSide = 0; thisSide <= 1; thisSide++ ) {
828 for (
size_t ielement = 0; ielement <
element [ thisSide ].size(); ielement++ ) {
836 for (
auto gp: *iRule ) {
839 FloatArray lcoords = gp->giveNaturalCoordinates();
846 for (
int j = 0; j <
ndof; j++ ) {
851 temp.
at(j+1) += normalSign*this->
g.dotProduct(gcoords)*fVal*gp->giveWeight()*detJ;
859 if (lock) omp_set_lock(
static_cast<omp_lock_t*
>(lock));
863 if (lock) omp_unset_lock(
static_cast<omp_lock_t*
>(lock));
868 answer.
times(factor);
871int WeakPeriodicBoundaryCondition :: giveNumberOfInternalDofManagers()
876DofManager *WeakPeriodicBoundaryCondition :: giveInternalDofManager(
int i)
885double WeakPeriodicBoundaryCondition :: factorial(
int n)
888 for (
int i = 1; i <= n; i++ ) {
894double WeakPeriodicBoundaryCondition :: binomial(
double n,
int k)
897 for (
int i = 1; i <= k; i++ ) {
898 f = f * ( n - ( k - i ) ) / i;
903void WeakPeriodicBoundaryCondition :: getExponents(
int term,
int &i,
int &j)
905 bool doContinue =
true;
913 while ( doContinue ) {
914 for (
int t = 0; t <= n; t++ ) {
#define REGISTER_BoundaryCondition(class)
ActiveBoundaryCondition(int n, Domain *d)
virtual void giveBoundaryLocationArray(IntArray &locationArray, const IntArray &bNodes, const UnknownNumberingScheme &s, IntArray *dofIds=NULL)
virtual FEInterpolation * giveInterpolation() const
void computeVectorOf(ValueModeType u, TimeStep *tStep, FloatArray &answer)
void computeBoundaryVectorOf(const IntArray &bNodes, const IntArray &dofIDMask, ValueModeType u, TimeStep *tStep, FloatArray &answer, bool padding=false)
virtual Element_Geometry_Type giveGeometryType() const =0
virtual std::unique_ptr< IntegrationRule > giveBoundaryIntegrationRule(int order, int boundary, const Element_Geometry_Type) const
virtual IntArray boundaryGiveNodes(int boundary, const Element_Geometry_Type) const =0
virtual int global2local(FloatArray &answer, const FloatArray &gcoords, const FEICellGeometry &cellgeo) const =0
virtual double boundaryGiveTransformationJacobian(int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
virtual void boundaryLocal2Global(FloatArray &answer, int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
virtual double evaldNdx(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
virtual double boundaryEvalNormal(FloatArray &answer, int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
virtual void boundaryEvalN(FloatArray &answer, int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
Domain * giveDomain() const
Domain * domain
Link to domain object, useful for communicating with other FEM components.
void assemble(const FloatArray &fe, const IntArray &loc)
void plusProduct(const FloatMatrix &b, const FloatArray &s, double dV)
Index giveSize() const
Returns the size of receiver.
virtual void printYourself() const
void zero()
Zeroes all coefficients of receiver.
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
void assembleSquared(const FloatArray &fe, const IntArray &loc)
void add(const FloatMatrix &a)
void resize(Index rows, Index cols)
int giveNumberOfColumns() const
Returns number of columns of receiver.
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
void beTranspositionOf(const FloatMatrix &src)
void zero()
Zeroes all coefficient of receiver.
bool beInverseOf(const FloatMatrix &src)
*Prints matrix to stdout Useful for debugging void printYourself() const
void beMatrixForm(const FloatArray &aArray)
int giveNumberOfRows() const
Returns number of rows of receiver.
double at(std::size_t i, std::size_t j) const
void beTProductOf(const FloatMatrix &a, const FloatMatrix &b)
Function * giveTimeFunction()
virtual void scale(double s)
virtual int assemble(const IntArray &loc, const FloatMatrix &mat)=0
int giveNumber()
Returns receiver's number.
std ::unique_ptr< Node > gammaDman
void computeDeformationGradient(FloatMatrix &answer, Element *e, FloatArray *lcoord, TimeStep *tStep)
double computeProjectionCoefficient(int vIndex, int uIndex)
void computeOrthogonalBasis()
void giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, CharType type, ValueModeType mode, const UnknownNumberingScheme &s, FloatArray *eNorm=nullptr, void *lock=nullptr)
double computeBaseFunctionValue(int baseID, FloatArray coordinate)
std ::vector< int > element[2]
double binomial(double n, int k)
std ::vector< int > side[2]
void giveEdgeNormal(FloatArray &answer, int element, int side)
void getExponents(int n, int &i, int &j)
void giveExternalForcesVector(FloatArray &answer, TimeStep *tStep, CharType type, ValueModeType mode, const UnknownNumberingScheme &s, void *lock=nullptr)
double computeBaseFunctionValue2D(int baseID, FloatArray coordinate)
double computeBaseFunctionValue1D(int baseID, double coordinate)
static FloatArray Vec2(const double &a, const double &b)
#define _IFT_WeakPeriodicBoundaryCondition_nlgeo
#define _IFT_WeakPeriodicBoundaryCondition_elementSidesNegative
#define _IFT_WeakPeriodicBoundaryCondition_elementSidesPositiveSet
#define _IFT_WeakPeriodicBoundaryCondition_gradient
#define _IFT_WeakPeriodicBoundaryCondition_descritizationType
#define _IFT_WeakPeriodicBoundaryCondition_elementSidesPositive
#define _IFT_WeakPeriodicBoundaryCondition_order
#define _IFT_WeakPeriodicBoundaryCondition_dofids
#define _IFT_WeakPeriodicBoundaryCondition_elementSidesNegativeSet