71void TransportGradientDirichlet :: initializeFrom(
InputRecord &ir)
73 GeneralBoundaryCondition :: initializeFrom(ir);
98 return GeneralBoundaryCondition :: giveInputRecord(input);
102void TransportGradientDirichlet :: postInitialize()
104 BoundaryCondition :: postInitialize();
110double TransportGradientDirichlet :: give(
Dof *dof, ValueModeType mode,
double time)
114 if ( coords.giveSize() != this->mCenterCoord.giveSize() ) {
115 OOFEM_ERROR(
"Size of coordinate system different from center coordinate in b.c.");
119 if ( mode == VM_Total ) {
121 }
else if ( mode == VM_Velocity ) {
123 }
else if ( mode == VM_Acceleration ) {
126 OOFEM_ERROR(
"Should not be called for value mode type then total, velocity, or acceleration.");
132 if ( !
xis.empty() ) {
136 return mGradient.dotProduct(dx) * factor;
140double TransportGradientDirichlet :: domainSize()
143 int nsd =
domain->giveNumberOfSpatialDimensions();
144 double domain_size = 0.0;
146 for (
auto &surf : this->
surfSets ) {
147 const IntArray &boundaries =
domain->giveSet(surf)->giveBoundaryList();
149 for (
int pos = 1; pos <= boundaries.
giveSize() / 2; ++pos ) {
151 int boundary = boundaries.
at(pos * 2);
159 for (
int pos = 1; pos <= boundaries.
giveSize() / 2; ++pos ) {
161 int boundary = boundaries.
at(pos * 2);
166 return fabs(domain_size / nsd);
170void TransportGradientDirichlet :: computeCoefficientMatrix(
FloatMatrix &C)
177 int nsd =
domain->giveNumberOfSpatialDimensions();
182 for (
auto &n :
domain->giveDofManagers() ) {
183 const auto &coords = n->giveCoordinates();
184 Dof *d1 = n->giveDofWithID( this->
dofs[0] );
190 xi =
xis[n->giveNumber()];
192 for (
int i = 1; i <= nsd; ++i ) {
236 std :: unique_ptr< SparseLinearSystemNM >solver(
classFactory.createSparseLinSolver(
ST_Petsc, this->domain, this->domain->giveEngngModel() ) );
242 std :: unique_ptr< SparseMtrx >Kff(
classFactory.createSparseMtrx(stype) );
244 std :: unique_ptr< SparseMtrx >Kpf(
classFactory.createSparseMtrx(stype) );
245 std :: unique_ptr< SparseMtrx >Kpp(
classFactory.createSparseMtrx(stype) );
247 OOFEM_ERROR(
"Couldn't create sparse matrix of type %d\n", stype);
249 Kff->buildInternalStructure(rve, 1, fnum);
251 Kpf->buildInternalStructure(rve, 1, pnum, fnum);
252 Kpp->buildInternalStructure(rve, 1, pnum);
266 int nelem =
domain->giveNumberOfElements();
268 #pragma omp parallel for shared(Kff, Kpf, Kpp) private(mat, R, floc, ploc)
270 for (
int ielem = 1; ielem <= nelem; ielem++ ) {
279 ma.matrixFromElement(mat, *element, tStep);
282 ma.locationFromElement(floc, *element, fnum);
283 ma.locationFromElement(ploc, *element, pnum);
293 Kff->assemble(floc, mat);
294 Kpf->assemble(ploc, floc, mat);
295 Kpp->assemble(ploc, mat);
299 Kff->assembleBegin();
300 Kpf->assembleBegin();
301 Kpp->assembleBegin();
313 Kpf->timesT(C, KfpC);
317 int nsd =
domain->giveNumberOfSpatialDimensions();
318 for (
auto &n :
domain->giveDofManagers() ) {
319 int k1 = n->giveDofWithID( this->
dofs[0] )->__giveEquationNumber();
321 const auto &coords = n->giveCoordinates();
322 for (
int i = 1; i <= nsd; ++i ) {
334 Kpf->times(sol, Kpfa);
341void TransportGradientDirichlet :: computeXi()
345 std :: unique_ptr< SparseLinearSystemNM > solver(
classFactory.createSparseLinSolver(
ST_Petsc, this->giveDomain(), this->giveDomain()->giveEngngModel()) );
349 for (
int node :
domain->giveSet(this->giveSetNumber())->giveNodeList() ) {
352 for (
auto &surf : this->
surfSets ) {
353 for (
int node :
domain->giveSet(surf)->giveNodeList() ) {
360 std :: vector< std :: vector< int > > surf2edges = {{1, 2, 3, 4},
370 std :: vector< Set > edgeSets;
371 std :: vector< std :: vector< std :: tuple< int, int > > > surfedges( this->surfSets.giveSize() );
372 for (
int i = 0; i < this->surfSets.giveSize(); ++i ) {
374 surfedges[i].reserve( 4 * surfs.
giveSize() / 2 );
375 for (
int pos = 0; pos < surfs.
giveSize() / 2; ++pos ) {
376 for (
int edgenum : surf2edges[surfs[pos * 2 + 1]-1] ) {
377 surfedges[i].emplace_back( std :: make_tuple(surfs[pos * 2], edgenum) );
382 for (
int i = 0; i < this->surfSets.giveSize() - 1; ++i ) {
383 for (
int j = i+1; j < this->surfSets.giveSize(); ++j ) {
384 std :: vector< std :: tuple< int, int > > ijEdgeSet;
385 std :: set_intersection(surfedges[i].begin(), surfedges[i].end(),
386 surfedges[j].begin(), surfedges[j].end(), std::back_inserter(ijEdgeSet));
389 for (
auto &edge : ijEdgeSet ) {
397 edgeSets.emplace_back(std :: move(s));
406 for (
auto &setPointer : edgeSets ) {
407 const IntArray &nodes = setPointer.giveNodeList();
408 for (
int n : nodes ) {
419 for (
auto &setPointer : edgeSets ) {
420 const IntArray &edges = setPointer.giveEdgeList();
423 std :: map< int, int > eqs;
425 for (
int n : setPointer.giveNodeList() ) {
436 std :: unique_ptr< SparseMtrx > K(
classFactory.createSparseMtrx(solver->giveRecommendedMatrix(
true)) );
437 K->buildInternalStructure(
domain->giveEngngModel(), eq_count, eq_count, {}, {});
441 for (
int pos = 0; pos < edges.
giveSize() / 2; ++pos ) {
443 int edge = edges[pos * 2 + 1];
455 for (
auto &gp: *ir ) {
456 const FloatArray &lcoords = gp->giveNaturalCoordinates();
462 double dL = detJ * gp->giveWeight();
469 for (
int i = 1; i <= b.
giveSize(); ++i ) {
477 double k = D.
at(1,1);
487 for (
int i = 1; i <= bNodes.giveSize(); ++i ) {
488 int enode = bNodes.at(i);
491 cvec.
at(i, 1) = x.at(1);
492 cvec.
at(i, 2) = x.at(2);
493 cvec.
at(i, 3) = x.at(3);
500 K->assemble(loc, Ke);
505 solver->solve(*K, f, x);
507 for (
int n : setPointer.giveNodeList() ) {
510 this->
xis[n] = {x.
at(eq, 1), x.
at(eq, 2), x.
at(eq, 3)};
524 std :: map< int, int > eqs;
537 std :: unique_ptr< SparseMtrx > K(
classFactory.createSparseMtrx(solver->giveRecommendedMatrix(
true)) );
538 K->buildInternalStructure(
domain->giveEngngModel(), eq_count, eq_count, {}, {});
544 for (
int pos = 0; pos < surfs.
giveSize() / 2; ++pos ) {
546 int surf = surfs[pos * 2 + 1];
556 for (
auto &gp: *ir ) {
557 const FloatArray &lcoords = gp->giveNaturalCoordinates();
565 double dA = detJ * gp->giveWeight();
570 for (
int k = 1; k <= 3; ++k ) {
571 tmp += normal.
at(k) * B.
at(k,j);
573 B.
at(i,j) -= normal.
at(i) * tmp;
591 for (
int i = 1; i <= bNodes.giveSize(); ++i ) {
592 int enode = bNodes.at(i);
595 cvec.
at(i, 1) = x.
at(1);
596 cvec.
at(i, 2) = x.
at(2);
597 cvec.
at(i, 3) = x.
at(3);
603 K->assemble(loc, Ke);
622 solver->solve(*K, q, qx);
623 solver->solve(*K, f, x);
633 this->
xis[n] = {x.
at(eq, 1), x.
at(eq, 2), x.
at(eq, 3)};
#define REGISTER_BoundaryCondition(class)
const FloatArray & giveCoordinates() const
DofManager * giveDofManager() const
virtual int __givePrescribedEquationNumber()=0
Node * giveNode(int i) const
virtual bool giveRotationMatrix(FloatMatrix &answer)
virtual bool isActivated(TimeStep *tStep)
virtual FEInterpolation * giveInterpolation() const
elementParallelMode giveParallelMode() const
virtual IntegrationRule * giveDefaultIntegrationRulePtr()
virtual Element_Geometry_Type giveGeometryType() const =0
virtual int giveNumberOfDomainEquations(int di, const UnknownNumberingScheme &num)
virtual void assemble(SparseMtrx &answer, TimeStep *tStep, const MatrixAssembler &ma, const UnknownNumberingScheme &s, Domain *domain)
void assembleVector(FloatArray &answer, TimeStep *tStep, const VectorAssembler &va, ValueModeType mode, const UnknownNumberingScheme &s, Domain *domain, FloatArray *eNorms=NULL)
IntArray boundaryEdgeGiveNodes(int boundary, const Element_Geometry_Type, bool includeHierarchical=false) const override
std::unique_ptr< IntegrationRule > giveBoundaryIntegrationRule(int _order, int boundary, const Element_Geometry_Type) const override
double boundaryEvalNormal(FloatArray &answer, int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
virtual void surfaceEvaldNdx(FloatMatrix &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
double boundaryEdgeGiveTransformationJacobian(int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
void boundaryEvalN(FloatArray &answer, int boundary, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const override
IntArray boundaryGiveNodes(int boundary, const Element_Geometry_Type) const override
std::unique_ptr< IntegrationRule > giveBoundaryEdgeIntegrationRule(int order, int boundary, const Element_Geometry_Type) const override
virtual void edgeEvaldNdxi(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const
virtual double evalNXIntegral(int boundary, const FEICellGeometry &cellgeo) const
int giveInterpolationOrder() const
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
Index giveSize() const
Returns the size of receiver.
void zero()
Zeroes all coefficients of receiver.
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
void beScaled(double s, const FloatArray &b)
void beTProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
void add(const FloatArray &src)
void rotatedWith(const FloatMatrix &r, char mode='n')
void plusProductSymmUpper(const FloatMatrix &a, const FloatMatrix &b, double dV)
void resize(Index rows, Index cols)
int giveNumberOfColumns() const
Returns number of columns of receiver.
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
void plusDyadUnsym(const FloatArray &a, const FloatArray &b, double dV)
void beTranspositionOf(const FloatMatrix &src)
void zero()
Zeroes all coefficient of receiver.
bool isNotEmpty() const
Tests for empty matrix.
void plusDyadSymmUpper(const FloatArray &a, double dV)
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
void subtract(const FloatMatrix &a)
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 insertSortedOnce(int value, int allocChunk=0)
void followedBy(const IntArray &b, int allocChunk=0)
bool containsSorted(int value) const
void preallocate(int futureSize)
GaussPoint * getIntegrationPoint(int n)
void setEdgeList(IntArray newEdges)
const IntArray & giveBoundaryList()
const IntArray & giveNodeList()
double getUtime()
Returns total user time elapsed in seconds.
void computeCoefficientMatrix(FloatMatrix &C)
std ::map< int, FloatArray > xis
Stores one "psi" value for each node.
void computeXi()
Computes the offset values for "improved" Dirichlet. See class description.
#define OOFEM_LOG_INFO(...)
@ Element_remote
Element in active domain is only mirror of some remote element.
ClassFactory & classFactory
#define _IFT_TransportGradientDirichlet_gradient
#define _IFT_TransportGradientDirichlet_centerCoords
#define _IFT_TransportGradientDirichlet_surfSets
#define _IFT_TransportGradientDirichlet_tractionControl