70 int dofid = this->
domain->giveNextFreeDofID();
71 v_id.followedBy(dofid);
76MixedGradientPressureWeakPeriodic :: ~MixedGradientPressureWeakPeriodic()
81int MixedGradientPressureWeakPeriodic :: giveNumberOfInternalDofManagers()
87DofManager *MixedGradientPressureWeakPeriodic :: giveInternalDofManager(
int i)
97void MixedGradientPressureWeakPeriodic :: initializeFrom(
InputRecord &ir)
99 MixedGradientPressureBC :: initializeFrom(ir);
102 if ( this->
order < 0 ) {
106 int nsd = this->
domain->giveNumberOfSpatialDimensions();
107 int total = nsd * nsd * ( int ) pow(
double (
order + 1 ), nsd - 1);
110 for (
int i = 1; i <= total; ++i ) {
111 int dofid = this->
domain->giveNextFreeDofID();
112 t_id.followedBy(dofid);
120void MixedGradientPressureWeakPeriodic :: setPrescribedDeviatoricGradientFromVoigt(
const FloatArray &t)
124 for (
int i = 1; i <= this->
devGradient.giveNumberOfRows(); i++ ) {
135 d.
at(1, 1) = d_voigt.
at(1);
136 d.
at(2, 2) = d_voigt.
at(2);
137 d.
at(3, 3) = d_voigt.
at(3);
138 d.
at(2, 3) = d.
at(3, 2) = d_voigt.
at(4) * 0.5;
139 d.
at(1, 3) = d.
at(3, 1) = d_voigt.
at(5) * 0.5;
140 d.
at(1, 2) = d.
at(2, 1) = d_voigt.
at(6) * 0.5;
141 }
else if ( n == 3 ) {
143 d.
at(1, 1) = d_voigt.
at(1);
144 d.
at(2, 2) = d_voigt.
at(2);
145 d.
at(1, 2) = d.
at(2, 1) = d_voigt.
at(3) * 0.5;
146 }
else if ( n == 1 ) {
148 d.
at(1, 1) = d_voigt.
at(1);
155void MixedGradientPressureWeakPeriodic :: giveLocationArrays(std :: vector< IntArray > &rows, std :: vector< IntArray > &cols,
CharType type,
158 if ( type != TangentStiffnessMatrix ) {
162 IntArray loc_r, loc_c, t_loc_r, t_loc_c, e_loc_r, e_loc_c;
169 this->
voldman->giveLocationArray(
v_id, e_loc_r, r_s);
170 this->
voldman->giveLocationArray(
v_id, e_loc_c, c_s);
173 const IntArray &boundaries =
set->giveBoundaryList();
175 rows.resize(boundaries.
giveSize() + 2);
176 cols.resize(boundaries.
giveSize() + 2);
178 for (
int pos = 1; pos <= boundaries.
giveSize() / 2; ++pos ) {
180 int boundary = boundaries.
at(pos * 2);
187 cols [ i ] = t_loc_c;
190 rows [ i ] = t_loc_r;
196 rows [ i ] = t_loc_r;
197 cols [ i ] = e_loc_c;
200 rows [ i ] = e_loc_r;
201 cols [ i ] = t_loc_c;
206void MixedGradientPressureWeakPeriodic :: evaluateTractionBasisFunctions(
FloatArray &answer,
const FloatArray &surfCoords)
209 int total = ( int ) pow(
double (
order + 1 ), surfCoords.
giveSize());
213 for (
int xi = 0; xi < ( this->
order + 1 ); ++xi ) {
215 for (
int yi = 0; yi < ( this->
order + 1 ); ++yi ) {
216 answer(pos) = tx * ty;
228 int nsd = this->
giveDomain()->giveNumberOfSpatialDimensions();
229 int total = nsd * nsd * ( int ) pow(
double ( this->
order + 1 ), nsd - 1);
231 surfCoords.
resize(nsd - 1);
232 mMatrix.
resize(nsd, total);
235 for (
int kj = 0; kj < nsd; ++kj ) {
237 for (
int c = 0, q = 0; c < nsd; ++c ) {
239 surfCoords(q) = coords(c);
245 for (
int ti = 0; ti < t.
giveSize(); ++ti ) {
246 for (
int ki = 0; ki < nsd; ++ki ) {
247 mMatrix(ki, pos) = t(ti) * normal(kj);
255void MixedGradientPressureWeakPeriodic :: integrateTractionVelocityTangent(
FloatMatrix &answer,
Element *el,
int boundary)
265 int nsd = this->
giveDomain()->giveNumberOfSpatialDimensions();
269 const FloatArray &lcoords = gp->giveNaturalCoordinates();
285void MixedGradientPressureWeakPeriodic :: integrateTractionXTangent(
FloatMatrix &answer,
Element *el,
int boundary)
298 const FloatArray &lcoords = gp->giveNaturalCoordinates();
307 tmpAnswer.
plusProduct(mMatrix, vM_vol, detJ * gp->giveWeight());
327 const FloatArray &lcoords = gp->giveNaturalCoordinates();
337 answer.
plusProduct(mMatrix, vM_dev, detJ * gp->giveWeight());
349 const IntArray &boundaries =
set->giveBoundaryList();
356 if ( type == ExternalForcesVector ) {
362 if (lock) omp_set_lock(
static_cast<omp_lock_t*
>(lock));
369 if (lock) omp_unset_lock(
static_cast<omp_lock_t*
>(lock));
375 for (
int pos = 1; pos <= boundaries.
giveSize() / 2; ++pos ) {
377 int boundary = boundaries.
at(pos * 2);
382 if (lock) omp_set_lock(
static_cast<omp_lock_t*
>(lock));
389 if (lock) omp_unset_lock(
static_cast<omp_lock_t*
>(lock));
392 }
else if ( type == InternalForcesVector ) {
399 this->
voldman->giveUnknownVector(e,
v_id, mode, tStep);
404 for (
int pos = 1; pos <= boundaries.
giveSize() / 2; ++pos ) {
406 int boundary = boundaries.
at(pos * 2);
426 if (lock) omp_set_lock(
static_cast<omp_lock_t*
>(lock));
437 if (lock) omp_unset_lock(
static_cast<omp_lock_t*
>(lock));
449 if ( type == TangentStiffnessMatrix || type == SecantStiffnessMatrix || type == ElasticStiffnessMatrix ) {
451 IntArray v_loc_r, v_loc_c, t_loc_r, t_loc_c, e_loc_r, e_loc_c;
453 const IntArray &boundaries =
set->giveBoundaryList();
459 this->
voldman->giveLocationArray(
v_id, e_loc_r, r_s);
460 this->
voldman->giveLocationArray(
v_id, e_loc_c, c_s);
462 for (
int pos = 1; pos <= boundaries.
giveSize() / 2; ++pos ) {
464 int boundary = boundaries.
at(pos * 2);
480 if (lock) omp_set_lock(
static_cast<omp_lock_t*
>(lock));
482 answer.
assemble(t_loc_r, v_loc_c, Ke_v);
483 answer.
assemble(v_loc_r, t_loc_c, Ke_vT);
485 answer.
assemble(t_loc_r, e_loc_c, Ke_e);
486 answer.
assemble(e_loc_r, t_loc_c, Ke_eT);
488 if (lock) omp_unset_lock(
static_cast<omp_lock_t*
>(lock));
495void MixedGradientPressureWeakPeriodic :: computeFields(
FloatArray &sigmaDev,
double &vol,
TimeStep *tStep)
503 vol = (*this->
voldman->begin())->giveUnknown(VM_Total, tStep);
509void MixedGradientPressureWeakPeriodic :: computeStress(
FloatArray &sigmaDev,
FloatArray &tractions,
double rve_size)
514 int nsd =
domain->giveNumberOfSpatialDimensions();
516 const IntArray &boundaries =
set->giveBoundaryList();
522 for (
int pos = 1; pos <= boundaries.
giveSize() / 2; ++pos ) {
524 int boundary = boundaries.
at(pos * 2);
532 const FloatArray &lcoords = gp->giveNaturalCoordinates();
544 sigma.
times(1. / rve_size);
547 for (
int i = 1; i <= nsd; i++ ) {
556 sigmaDev.
at(4) = 0.5 * ( sigma.
at(2, 3) + sigma.
at(3, 2) );
557 sigmaDev.
at(5) = 0.5 * ( sigma.
at(1, 3) + sigma.
at(3, 1) );
558 sigmaDev.
at(6) = 0.5 * ( sigma.
at(1, 2) + sigma.
at(2, 1) );
559 }
else if ( nsd == 2 ) {
563 sigmaDev.
at(3) = 0.5 * ( sigma.
at(1, 2) + sigma.
at(2, 1) );
576 std :: unique_ptr< SparseLinearSystemNM > solver(
581 const IntArray &boundaries =
set->giveBoundaryList();
585 std :: unique_ptr< SparseMtrx > Kff(
classFactory.createSparseMtrx(stype) );
587 OOFEM_ERROR(
"Couldn't create sparse matrix of type %d\n", stype);
589 Kff->buildInternalStructure(rve, this->
domain->giveNumber(), fnum);
593 int neq = Kff->giveNumberOfRows();
597 int nd = nsd * ( 1 + nsd ) / 2;
603 this->
voldman->giveLocationArray(
v_id, e_loc, fnum );
614 for (
int i = 1; i <= nd; ++i ) {
616 FloatArray tmp(neq), fe, fetot, ddevVoigt(nd);
617 ddevVoigt.
at(i) = 1.0;
619 for (
int k = 1; k <= boundaries.
giveSize() / 2; ++k ) {
621 int boundary = boundaries.
at(k * 2);
626 tmp.assemble(fetot, t_loc);
632 p_pert.
at( e_loc.at(1) ) = - 1.0 * rve_size;
635 solver->solve(*Kff, ddev_pert, s_d);
636 solver->solve(*Kff, p_pert, s_p);
642 for (
int i = 1; i <= nd; ++i ) {
643 for (
int k = 1; k <= t_loc.giveSize(); ++k ) {
644 tractions_d.
at(k, i) = s_d.
at(t_loc.at(k), i);
649 Cp = - s_p.
at( e_loc.at(1) );
653 Cd.
at(1) = s_d.
at(e_loc.at(1), 1);
654 Cd.
at(2) = s_d.
at(e_loc.at(1), 2);
655 Cd.
at(3) = s_d.
at(e_loc.at(1), 3);
656 Cd.
at(4) = s_d.
at(e_loc.at(1), 4);
657 Cd.
at(5) = s_d.
at(e_loc.at(1), 5);
658 Cd.
at(6) = s_d.
at(e_loc.at(1), 6);
659 }
else if ( nsd == 2 ) {
660 Cd.
at(1) = s_d.
at(e_loc.at(1), 1);
661 Cd.
at(2) = s_d.
at(e_loc.at(1), 2);
662 Cd.
at(3) = s_d.
at(e_loc.at(1), 3);
668 for (
int dpos = 1; dpos <= nd; ++dpos ) {
678 MixedGradientPressureBC :: giveInputRecord(input);
685void MixedGradientPressureWeakPeriodic :: scale(
double s)
#define REGISTER_BoundaryCondition(class)
virtual void giveBoundaryLocationArray(IntArray &locationArray, const IntArray &bNodes, const UnknownNumberingScheme &s, IntArray *dofIds=NULL)
virtual FEInterpolation * giveInterpolation() const
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 void assemble(SparseMtrx &answer, TimeStep *tStep, const MatrixAssembler &ma, const UnknownNumberingScheme &s, Domain *domain)
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
int giveInterpolationOrder() const
virtual void boundaryLocal2Global(FloatArray &answer, int boundary, 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.
void beColumnOf(const FloatMatrix &mat, int col)
void zero()
Zeroes all coefficients of receiver.
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
void assembleSquared(const FloatArray &fe, const IntArray &loc)
void beScaled(double s, const FloatArray &b)
void beTProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
void add(const FloatArray &src)
void subtract(const FloatArray &src)
void beSubArrayOf(const FloatArray &src, const IntArray &indx)
void resize(Index rows, Index cols)
*Sets size of receiver to be an empty matrix It will have zero rows and zero columns size void clear()
void plusProductUnsym(const FloatMatrix &a, const FloatMatrix &b, double dV)
void beNMatrixOf(const FloatArray &n, int nsd)
void plusDyadUnsym(const FloatArray &a, const FloatArray &b, double dV)
void setColumn(const FloatArray &src, int c)
void beTranspositionOf(const FloatMatrix &src)
void zero()
Zeroes all coefficient of receiver.
double at(std::size_t i, std::size_t j) const
int set
Set number for boundary condition to be applied to.
IntArray dofs
Dofs that b.c. is applied to (relevant for Dirichlet type b.c.s).
MixedGradientPressureBC(int n, Domain *d)
double pressure
Prescribed pressure.
int order
Order if polynomials.
void scale(double s) override
void constructMMatrix(FloatMatrix &mMatrix, FloatArray &coords, FloatArray &normal)
std ::unique_ptr< Node > tractionsdman
DOF-manager containing the unknown tractions (Lagrange mult. for micro-periodic velocity).
void computeStress(FloatArray &sigmaDev, FloatArray &tractions, double rve_size)
void constructFullMatrixForm(FloatMatrix &d, const FloatArray &d_voigt) const
void evaluateTractionBasisFunctions(FloatArray &answer, const FloatArray &coords)
std ::unique_ptr< Node > voldman
DOF-manager containing the unknown volumetric gradient (always exactly one dof).
FloatMatrix devGradient
Prescribed gradient .
void integrateTractionXTangent(FloatMatrix &answer, Element *el, int boundary)
void integrateTractionVelocityTangent(FloatMatrix &answer, Element *el, int boundary)
void integrateTractionDev(FloatArray &answer, Element *el, int boundary, const FloatMatrix &ddev)
virtual int assemble(const IntArray &loc, const FloatMatrix &mat)=0
#define _IFT_MixedGradientPressure_pressure
#define _IFT_MixedGradientPressureWeakPeriodic_order
Order of global polynomial in the unknown tractions. Should be at least 1.
ClassFactory & classFactory