62TransportGradientNeumann :: TransportGradientNeumann(
int n,
Domain *d) :
68 for (
int i = 0; i < nsd; i++ ) {
77void TransportGradientNeumann :: initializeFrom(
InputRecord &ir)
79 ActiveBoundaryCondition :: initializeFrom(ir);
99void TransportGradientNeumann :: postInitialize()
101 ActiveBoundaryCondition :: postInitialize();
107DofManager *TransportGradientNeumann :: giveInternalDofManager(
int i)
112void TransportGradientNeumann :: scale(
double s)
117double TransportGradientNeumann :: domainSize()
120 int nsd =
domain->giveNumberOfSpatialDimensions();
121 double domain_size = 0.0;
123 for (
auto &setNum : this->
surfSets ) {
125 const IntArray &boundaries =
set->giveBoundaryList();
127 for (
int pos = 0; pos < boundaries.
giveSize() / 2; ++pos ) {
129 int boundary = boundaries[pos * 2 + 1];
134 return fabs(domain_size / nsd);
146 if ( type == ExternalForcesVector ) {
154 if (lock) omp_set_lock(
static_cast<omp_lock_t*
>(lock));
156 answer.
assemble(fluxLoad, flux_loc);
158 if (lock) omp_unset_lock(
static_cast<omp_lock_t*
>(lock));
160 }
else if ( type == InternalForcesVector ) {
164 IntArray loc, masterDofIDs, fluxMasterDofIDs;
172 for (
int i = 0; i < this->
surfSets.giveSize(); ++i ) {
176 for (
int pos = 0; pos < boundaries.
giveSize() / 2; ++pos ) {
178 int boundary = boundaries[pos * 2 + 1];
194 if (lock) omp_set_lock(
static_cast<omp_lock_t*
>(lock));
198 if ( eNorm != NULL ) {
203 if (lock) omp_unset_lock(
static_cast<omp_lock_t*
>(lock));
215 if ( type == TangentStiffnessMatrix || type == SecantStiffnessMatrix || type == ElasticStiffnessMatrix ) {
217 IntArray loc_r, loc_c, flux_loc_r, flux_loc_c;
223 for (
int i = 0; i < this->
surfSets.giveSize(); ++i ) {
226 const IntArray &boundaries =
set->giveBoundaryList();
227 for (
int pos = 0; pos < boundaries.
giveSize() / 2; ++pos ) {
229 int boundary = boundaries[pos * 2 + 1];
239 if (lock) omp_set_lock(
static_cast<omp_lock_t*
>(lock));
241 answer.
assemble(flux_loc_r, loc_c, Ke);
242 answer.
assemble(loc_r, flux_loc_c, KeT);
244 if (lock) omp_unset_lock(
static_cast<omp_lock_t*
>(lock));
249 printf(
"Skipping assembly in TransportGradientNeumann::assemble().\n");
253void TransportGradientNeumann :: giveLocationArrays(std :: vector< IntArray > &rows, std :: vector< IntArray > &cols,
CharType type,
256 IntArray loc_r, loc_c, flux_loc_r, flux_loc_c;
266 for (
auto &surfSet : this->
surfSets ) {
268 const IntArray &boundaries =
set->giveBoundaryList();
270 rows.resize( rows.size() + boundaries.
giveSize() );
271 cols.resize( cols.size() + boundaries.
giveSize() );
272 for (
int pos = 0; pos < boundaries.
giveSize() / 2; ++pos ) {
274 int boundary = boundaries[pos * 2 + 1];
282 cols [ i ] = flux_loc_c;
285 rows [ i ] = flux_loc_r;
302 std :: unique_ptr< SparseLinearSystemNM > solver(
319 std :: unique_ptr< SparseMtrx > Kff(
classFactory.createSparseMtrx(stype) );
321 OOFEM_ERROR(
"Couldn't create sparse matrix of type %d\n", stype);
323 Kff->buildInternalStructure(rve, this->
domain->giveNumber(), fnum);
329 int neq = Kff->giveNumberOfRows();
332 for (
int i = 1; i <= neq; ++i ) {
338 std :: unique_ptr< SparseMtrx > Kuu = Kff->giveSubMatrix(loc_u, loc_u);
342 std :: unique_ptr< SparseMtrx > Kus = Kff->giveSubMatrix(loc_u, loc_s);
343 Kus->toFloatMatrix(KusD);
353 for (
int i = 0; i < this->
surfSets.giveSize(); ++i ) {
356 const IntArray &boundaries =
set->giveBoundaryList();
357 for (
int pos = 0; pos < boundaries.
giveSize() / 2; ++pos ) {
359 int boundary = boundaries[pos * 2 + 1];
368 KusD.
assemble(KeT, loc_r, {1, 2, 3});
382 int nsd =
domain->giveNumberOfSpatialDimensions();
386 for (
auto &e :
domain->giveElements() ) {
388 e->giveDefaultIntegrationRulePtr()->getIntegrationPoint(1), tStep);
389 double tmpVol = e->computeVolumeAreaOrLength();
392 Di.add(tmpVol, tmpDi);
397 for (
auto &n :
domain->giveDofManagers() ) {
398 int k1 = n->giveDofWithID( this->
dofs[0] )->__giveEquationNumber();
400 const auto &coords = n->giveCoordinates();
401 for (
int i = 1; i <= nsd; ++i ) {
408 Kuu->
times(us, KusD0);
423 tangent.
times(rve_size);
434void TransportGradientNeumann :: computeEta()
439 for (
int i = 0; i < this->
surfSets.giveSize(); ++i ) {
446 }
else if ( i % 3 == 1 ) {
471 for (
int pos = 0; pos < boundaries.
giveSize() / 2; ++pos ) {
473 int boundary = boundaries[pos * 2 + 1];
480 for (
auto &gp: *ir ) {
481 const FloatArray &lcoords = gp->giveNaturalCoordinates();
485 double dA = detJ * gp->giveWeight();
488 double r = coords[i_r], t = coords[i_t];
501 c(0, 1) += dA * k * r;
502 c(0, 2) += dA * k * t;
503 c(1, 0) += dA * k * r;
504 c(1, 1) += dA * k * r * r;
505 c(1, 2) += dA * k * t * r;
506 c(2, 0) += dA * k * t;
507 c(2, 1) += dA * k * r * t;
508 c(2, 2) += dA * k * t * t;
513 for (
int pos = 0; pos < boundaries.
giveSize() / 2; ++pos ) {
515 int boundary = boundaries[pos * 2 + 1];
522 eta[i][pos].resize(ir->giveNumberOfIntegrationPoints());
523 for (
auto &gp: *ir ) {
524 const FloatArray &lcoords = gp->giveNaturalCoordinates();
530 double r = coords[i_r], t = coords[i_t];
537 eta[i][pos].at(gp->giveNumber()) = (eta_c[0] + eta_c[1] * r + eta_c[2] * t) * k;
544void TransportGradientNeumann :: integrateTangent(
FloatMatrix &oTangent,
Element *e,
int boundary,
int surfSet,
int pos)
556 for (
auto &gp: *ir ) {
557 const FloatArray &lcoords = gp->giveNaturalCoordinates();
561 if ( !
eta.empty() ) {
563 scale =
eta[surfSet][pos].at(gp->giveNumber());
#define REGISTER_BoundaryCondition(class)
ActiveBoundaryCondition(int n, Domain *d)
int giveNextFreeDofID(int increment=1)
int giveNumberOfSpatialDimensions()
Returns number of spatial dimensions.
virtual void giveBoundaryLocationArray(IntArray &locationArray, const IntArray &bNodes, const UnknownNumberingScheme &s, IntArray *dofIds=NULL)
virtual FEInterpolation * giveInterpolation() const
virtual IntegrationRule * giveDefaultIntegrationRulePtr()
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
virtual double evalNXIntegral(int boundary, const FEICellGeometry &cellgeo) const
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)
double dotProduct(const FloatArray &x) const
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 subtract(const FloatArray &src)
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()
int giveNumberOfColumns() const
Returns number of columns of receiver.
void plusDyadUnsym(const FloatArray &a, const FloatArray &b, double dV)
void beTranspositionOf(const FloatMatrix &src)
bool beInverseOf(const FloatMatrix &src)
double computeFrobeniusNorm() const
int giveNumberOfRows() const
Returns number of rows of receiver.
void assemble(const FloatMatrix &src, const IntArray &loc)
double at(std::size_t i, std::size_t j) const
bool solveForRhs(const FloatArray &b, FloatArray &answer, bool transpose=false)
void beTProductOf(const FloatMatrix &a, const FloatMatrix &b)
int set
Set number for boundary condition to be applied to.
Function * giveTimeFunction()
IntArray dofs
Dofs that b.c. is applied to (relevant for Dirichlet type b.c.s).
bool contains(int value) const
GaussPoint * getIntegrationPoint(int n)
const IntArray & giveBoundaryList()
virtual int assemble(const IntArray &loc, const FloatMatrix &mat)=0
double giveTargetTime()
Returns target time.
virtual void computeConstitutiveMatrixAt(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep)
std ::vector< std ::vector< FloatArray > > eta
Scaling factor (one array per edge with one scaling factor per GP).
std ::unique_ptr< Node > mpFluxHom
DOF-manager containing the unknown homogenized stress.
void computeEta()
Help function computes phi by solving a diffusion problem on the RVE-surface.
void scale(double s) override
void integrateTangent(FloatMatrix &oTangent, Element *e, int iBndIndex, int surfSet, int pos)
Help function that integrates the tangent contribution from a single element boundary.
#define OOFEM_LOG_INFO(...)
ClassFactory & classFactory
#define _IFT_TransportGradientNeumann_surfSets
#define _IFT_TransportGradientNeumann_centerCoords
#define _IFT_TransportGradientNeumann_gradient
#define _IFT_TransportGradientNeumann_dispControl