diff --git a/AMDiS/src/Assembler.cc b/AMDiS/src/Assembler.cc index 6f2143ad4a0a8d0c8226463c62f42830c001720a..544580410b443309ef58819ebb097318602fa225 100644 --- a/AMDiS/src/Assembler.cc +++ b/AMDiS/src/Assembler.cc @@ -324,6 +324,9 @@ namespace AMDiS { calculateElementMatrix(elInfo, elementMatrix); } + // eventuell einfach + // vec = elementMatrix*uhOldLoc; + // schreiben for (int i = 0; i < nRow; i++) { double val = 0.0; for (int j = 0; j < nCol; j++) diff --git a/AMDiS/src/CouplingIterationInterface.cc b/AMDiS/src/CouplingIterationInterface.cc index 717b74eff67cb0d8e85069b7727220d1efade2c7..d241d26f35ebcde39f9f2230828038d2a0c5ff1b 100644 --- a/AMDiS/src/CouplingIterationInterface.cc +++ b/AMDiS/src/CouplingIterationInterface.cc @@ -43,9 +43,10 @@ namespace AMDiS { void CouplingIterationInterface::beginIteration(AdaptInfo *adaptInfo) { FUNCNAME("CouplingIterationInterface::beginIteration()"); MSG("\n"); + int nTimesteps = (adaptInfo->getNumberOfTimesteps() ? adaptInfo->getNumberOfTimesteps() : (adaptInfo->getEndTime()-adaptInfo->getStartTime())/adaptInfo->getTimestep()); MSG("begin of iteration number: %d/%d\n", adaptInfo->getTimestepNumber() + 1, - adaptInfo->getNumberOfTimesteps()); + nTimesteps); MSG("==================================================\n"); }; diff --git a/AMDiS/src/CouplingProblemStat.h b/AMDiS/src/CouplingProblemStat.h index 6351b3a5aa7ead21dd0681f10c05e840fbce12c3..581907f8f8829776734a0e90079d8d6cfddec197 100644 --- a/AMDiS/src/CouplingProblemStat.h +++ b/AMDiS/src/CouplingProblemStat.h @@ -166,7 +166,6 @@ namespace AMDiS { if (initMesh && meshes[i]) refinementManager->globalRefine(meshes[i], globalRefinements); } - } void createRefCoarseManager() diff --git a/AMDiS/src/DOFVector.h b/AMDiS/src/DOFVector.h index 8625f12cdfd6cd08759432e2f71778f4cdb2e474..4db016c5f822d10d8cf894fbaa960def78552f19 100644 --- a/AMDiS/src/DOFVector.h +++ b/AMDiS/src/DOFVector.h @@ -934,13 +934,6 @@ namespace AMDiS { TOut integrate_VecAndCoords(const DOFVector<T> &vec, BinaryAbstractFunction<TOut, T, WorldVector<double> > *fct); - template<typename TOut, typename T> - TOut integrate_VecAndCoords(const DOFVector<T> &vec, - BinaryAbstractFunction<TOut, T, WorldVector<double> > *fct) - { - return integrate(vec, fct); - } - /// Computes the integral: \f$ \int f(\{v_i(\vec{x})\}_i)\,\text{d}\vec{x}\f$ double integrateGeneral(const vector<DOFVector<double>*> &vecs, AbstractFunction<double, vector<double> > *fct); diff --git a/AMDiS/src/DOFVector.hh b/AMDiS/src/DOFVector.hh index b4bb8152e9c58ff212890943983fdef60db9f949..ffb06041eb8c87c832b8fba3bd40ac229627ca28 100644 --- a/AMDiS/src/DOFVector.hh +++ b/AMDiS/src/DOFVector.hh @@ -475,7 +475,7 @@ namespace AMDiS { const DOFAdmin* admin = this->getFeSpace()->getAdmin(); int nBasFcts = basFct->getNumber(); std::vector<DegreeOfFreedom> myLocalIndices(nBasFcts); - mtl::dense_vector<double> fctInterpolValues(nBasFcts); + mtl::dense_vector<T> fctInterpolValues(nBasFcts); TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(this->getFeSpace()->getMesh(), -1, @@ -513,14 +513,14 @@ namespace AMDiS { else flag |= Mesh::CALL_EL_LEVEL; - double result = 0.0; + T result; nullify(result); int nPoints = quadFast->getNumPoints(); mtl::dense_vector<T> uh_vec(nPoints); TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(mesh, meshLevel, flag); while (elInfo) { double det = elInfo->getDet(); - double normT = 0.0; + T normT; nullify(normT); this->getVecAtQPs(elInfo, NULL, quadFast, uh_vec); for (int iq = 0; iq < nPoints; iq++) normT += quadFast->getWeight(iq) * (uh_vec[iq]); @@ -769,7 +769,7 @@ namespace AMDiS { template<typename TOut, typename T> TOut integrate_VecAndCoords(const DOFVector<T> &vec, - BinaryAbstractFunction<T, T, WorldVector<double> > *fct) + BinaryAbstractFunction<TOut, T, WorldVector<double> > *fct) { FUNCNAME("integrate_VecAndCoords()"); diff --git a/AMDiS/src/Debug.cc b/AMDiS/src/Debug.cc index 73bfcaf76f7c2c6c36405efd6072f1cf14ecc3e1..752d692f297ac5c37dc56868e6def014275af1a6 100644 --- a/AMDiS/src/Debug.cc +++ b/AMDiS/src/Debug.cc @@ -106,7 +106,7 @@ namespace AMDiS { elInfo = stack.traverseNext(elInfo); } - ElementFileWriter::writeFile(vec, mesh, filename, "", level); + ElementFileWriter::writeFile(vec, mesh, filename, ".vtu", level); } diff --git a/AMDiS/src/ElInfo.cc b/AMDiS/src/ElInfo.cc index c9cffb3392eef81b8b40b169594240bcdc235f41..6ea21053152de4a29b6bd33485676dfca58aad1b 100644 --- a/AMDiS/src/ElInfo.cc +++ b/AMDiS/src/ElInfo.cc @@ -195,6 +195,11 @@ namespace AMDiS { void ElInfo::fillElInfo(const MacroElement *mel, int refinementPathLength, unsigned long refinementPath) { + if (refinementPathLength == 0) { + fillMacroInfo(mel); + return; + } + std::vector<ElInfo*> elInfo; elInfo.push_back(mesh->createNewElInfo()); elInfo.push_back(this); @@ -208,6 +213,7 @@ namespace AMDiS { } if (i%2 == 0) *this = *elInfo[0]; + delete elInfo[0]; } diff --git a/AMDiS/src/Functors.h b/AMDiS/src/Functors.h index ecf204456cf4517673f621db7a606e37da441457..fae87d69efa1acc54bebecf0f45033f8fd3cec4c 100644 --- a/AMDiS/src/Functors.h +++ b/AMDiS/src/Functors.h @@ -181,6 +181,15 @@ struct Norm2Sqr_comp3 : public TertiaryAbstractFunction<T,T,T,T> T operator()(const T &v1, const T &v2, const T &v3) const { return sqr(v1)+sqr(v2)+sqr(v3); } }; +template<typename T> +struct Vec1WorldVec : public AbstractFunction<WorldVector<T>,T> +{ + WorldVector<T> operator()(const T &v0) const { + WorldVector<T> result; + result[0]=v0; + return result; + } +}; template<typename T> struct Vec2WorldVec : public BinaryAbstractFunction<WorldVector<T>,T,T> { diff --git a/AMDiS/src/Initfile.h b/AMDiS/src/Initfile.h index 23c9e3615a0b8b01f44725e3a1582cf1cabe7889..33c0c21e404eb519767f7fd4061dafc55fdec3df 100644 --- a/AMDiS/src/Initfile.h +++ b/AMDiS/src/Initfile.h @@ -438,6 +438,11 @@ namespace AMDiS { initIntern(); if (debugInfo == -1) debugInfo = singlett->getMsgInfo(); + else { + int swap(debugInfo); + debugInfo = singlett->getMsgInfo(); + singlett->msgInfo=swap; + } std::string valStr; int error_code = singlett->checkedGet(tag, valStr); @@ -456,6 +461,7 @@ namespace AMDiS { std::cout << "Parameter '" << tag << "'" << " initialized with: " << value << std::endl; } + singlett->msgInfo = debugInfo; } diff --git a/AMDiS/src/MacroElement.h b/AMDiS/src/MacroElement.h index aed36d5239e765a4d765928d09adfb60e26863a3..ae2f988c6d439d0cc71e9fe1dd3d792bfea07e92 100644 --- a/AMDiS/src/MacroElement.h +++ b/AMDiS/src/MacroElement.h @@ -215,6 +215,7 @@ namespace AMDiS { friend class MacroInfo; friend class MacroReader; + friend class ElInfo; friend class ElInfo1d; friend class ElInfo2d; friend class ElInfo3d; diff --git a/AMDiS/src/Mesh.cc b/AMDiS/src/Mesh.cc index a7f7862834e3deec6f16799abbfa5ca80a140711..8664e00eb1fb7c203e987967e55c59dabce08353 100644 --- a/AMDiS/src/Mesh.cc +++ b/AMDiS/src/Mesh.cc @@ -1015,7 +1015,7 @@ namespace AMDiS { out << name << "\n"; - SerUtil::serialize(out, dim); +// SerUtil::serialize(out, dim); SerUtil::serialize(out, nVertices); SerUtil::serialize(out, nEdges); SerUtil::serialize(out, nLeaves); @@ -1095,8 +1095,8 @@ namespace AMDiS { in.get(); int oldVal = dim; - SerUtil::deserialize(in, dim); - TEST_EXIT_DBG(oldVal == 0 || dim == oldVal)("Invalid dimension!\n"); +// SerUtil::deserialize(in, dim); +// TEST_EXIT_DBG(oldVal == 0 || dim == oldVal)("Invalid dimension!\n"); SerUtil::deserialize(in, nVertices); SerUtil::deserialize(in, nEdges); diff --git a/AMDiS/src/SecondOrderTerm.cc b/AMDiS/src/SecondOrderTerm.cc index 1af5bd9ca7240d13e888b1ae997cd3a9a554111c..80edf2615214e91e49b450790b05477526eb7335 100644 --- a/AMDiS/src/SecondOrderTerm.cc +++ b/AMDiS/src/SecondOrderTerm.cc @@ -1365,4 +1365,87 @@ namespace AMDiS { } + // ========== Vec2AtQP_IJ_SOT ========== + + Vec2AtQP_IJ_SOT::Vec2AtQP_IJ_SOT(DOFVectorBase<double> *dv1, + DOFVectorBase<double> *dv2, + BinaryAbstractFunction<double, double, double> *af, + int x_i, int x_j) + : SecondOrderTerm(af ? af->getDegree() : dv1->getFeSpace()->getBasisFcts()->getDegree()+dv2->getFeSpace()->getBasisFcts()->getDegree()), + vec1(dv1), + vec2(dv2), + f(af), + xi(x_i), xj(x_j) + { + setSymmetric(xi == xj); + + TEST_EXIT(dv1)("No vector 1!\n"); + TEST_EXIT(dv2)("No vector 2!\n"); + + auxFeSpaces.insert(dv1->getFeSpace()); + auxFeSpaces.insert(dv2->getFeSpace()); + } + + void Vec2AtQP_IJ_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + getVectorAtQPs(vec1, elInfo, subAssembler, quad, vecAtQPs1); + getVectorAtQPs(vec2, elInfo, subAssembler, quad, vecAtQPs2); + } + + void Vec2AtQP_IJ_SOT::getLALt(const ElInfo *elInfo, + vector<mtl::dense2D<double> > &LALt) const + { + const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda(); + const int nPoints = static_cast<int>(LALt.size()); + + if (f) { + for (int iq = 0; iq < nPoints; iq++) + lalt_kl(grdLambda, xi, xj, LALt[iq], (*f)(vecAtQPs1[iq], vecAtQPs2[iq])); + } else { + for (int iq = 0; iq < nPoints; iq++) + lalt_kl(grdLambda, xi, xj, LALt[iq], vecAtQPs1[iq] * vecAtQPs2[iq]); + } + } + + void Vec2AtQP_IJ_SOT::eval(int nPoints, + const mtl::dense_vector<double>& uhAtQP, + const mtl::dense_vector<WorldVector<double> >& grdUhAtQP, + const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP, + mtl::dense_vector<double>& result, + double fac) + { + if (num_rows(D2UhAtQP) > 0) { + if (f) { + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*f)(vecAtQPs1[iq], vecAtQPs2[iq]); + result[iq] += D2UhAtQP[iq][xi][xj] * factor * fac; + } + } else { + for (int iq = 0; iq < nPoints; iq++) { + double factor = vecAtQPs1[iq] * vecAtQPs2[iq]; + result[iq] += D2UhAtQP[iq][xi][xj] * factor * fac; + } + } + } + } + + void Vec2AtQP_IJ_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + if (f) { + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*f)(vecAtQPs1[iq], vecAtQPs2[iq]); + result[iq][xi] += grdUhAtQP[iq][xj] * factor; + } + } else { + for (int iq = 0; iq < nPoints; iq++) { + double factor = vecAtQPs1[iq] * vecAtQPs2[iq]; + result[iq][xi] += grdUhAtQP[iq][xj] * factor; + } + } + } + } diff --git a/AMDiS/src/SecondOrderTerm.h b/AMDiS/src/SecondOrderTerm.h index a77acc27c43d5f842ef9db1b5304233233cb319e..b2f67ceaf82f887b17d03fd7afb1cd171d094f39 100644 --- a/AMDiS/src/SecondOrderTerm.h +++ b/AMDiS/src/SecondOrderTerm.h @@ -361,7 +361,7 @@ namespace AMDiS { { public: /// Constructor. - VecAtQP_SOT(DOFVectorBase<double> *dv, AbstractFunction<double, double> *af); + VecAtQP_SOT(DOFVectorBase<double> *dv, AbstractFunction<double, double> *af = NULL); /// Implementation of \ref OperatorTerm::initElement(). void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, @@ -411,8 +411,9 @@ namespace AMDiS { { public: /// Constructor. - Vec2AtQP_SOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, - BinaryAbstractFunction<double, double, double> *af); + Vec2AtQP_SOT(DOFVectorBase<double> *dv1, + DOFVectorBase<double> *dv2, + BinaryAbstractFunction<double, double, double> *af = NULL); /// Implementation of \ref OperatorTerm::initElement(). void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, @@ -1145,7 +1146,8 @@ namespace AMDiS { { public: /// Constructor. - VecAtQP_IJ_SOT(DOFVectorBase<double> *dv, AbstractFunction<double, double> *af, + VecAtQP_IJ_SOT(DOFVectorBase<double> *dv, + AbstractFunction<double, double> *af, int x_i, int x_j); /// Implementation of \ref OperatorTerm::initElement(). @@ -1182,6 +1184,59 @@ namespace AMDiS { int xi, xj; }; + /** + * \ingroup Assembler + * + * \brief + * SecondOrderTerm where A is a WorldMatrix having a in all positions + * except possibly the position IJ, multiplied with a function + * evaluated at the quadrature points of two given DOFVectors: + * \f$ \nabla \cdot f(v(\vec{x}),w(\vec{x})) A \nabla u(\vec{x}) \f$ + */ + class Vec2AtQP_IJ_SOT : public SecondOrderTerm + { + public: + /// Constructor. + Vec2AtQP_IJ_SOT(DOFVectorBase<double> *dv1, + DOFVectorBase<double> *dv2, + BinaryAbstractFunction<double, double, double> *af, + int x_i, int x_j); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements SecondOrderTerm::getLALt(). + void getLALt(const ElInfo *elInfo, vector<mtl::dense2D<double> > &LALt) const; + + /// Implements SecondOrderTerm::eval(). + void eval(int nPoints, + const mtl::dense_vector<double>& uhAtQP, + const mtl::dense_vector<WorldVector<double> >& grdUhAtQP, + const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP, + mtl::dense_vector<double>& result, + double factor); + + /// Implements SecondOrderTerm::weakEval(). + void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result); + + protected: + /// DOFVector to be evaluated at quadrature points. + DOFVectorBase<double>* vec1; + DOFVectorBase<double>* vec2; + + /// Pointer to an array containing the DOFVector evaluated at quadrature points. + mtl::dense_vector<double> vecAtQPs1; + mtl::dense_vector<double> vecAtQPs2; + + /// Function evaluated at \ref vecAtQPs. + BinaryAbstractFunction<double, double, double> *f; + + private: + /// Directions for the derivatives. + int xi, xj; + }; } #endif diff --git a/AMDiS/src/TransformDOF.h b/AMDiS/src/TransformDOF.h index 43432486f88915bb954ce485f42abeb02dab0cb2..e180186fc3ad18ea92f423f6f343bfca2a8b9b10 100644 --- a/AMDiS/src/TransformDOF.h +++ b/AMDiS/src/TransformDOF.h @@ -681,6 +681,7 @@ template<typename T1, typename T2, typename T3, typename T4> inline void transformDOF(T1 val, DOFVector<T2> &vec2, DOFVector<T3> &vec3, DOFVector<T4> &result, TertiaryAbstractFunction<T4, T1, T2, T3> &tertiary_op) { transformDOF(val, &vec2, &vec3, &result, &tertiary_op); } + // =========================================================================================== // return binary_op(vec, interpol(fct)) @@ -716,6 +717,40 @@ template<typename T> inline void transformDOFInterpolation( DOFVector<T> &vec, AbstractFunction<T, WorldVector<double> > &fct, DOFVector<T> &result, BinaryAbstractFunction<T, T, T> &binary_op) { transformDOFInterpolation(&vec, &fct, &result, &binary_op); } + +// ==================================================================================== + +template<typename T> +T accumulateDOF_simple(DOFVector<T> *vec, + T value0, + BinaryAbstractFunction<T, T, T> *binary_op) +{ + DOFIterator<T> vecIter(vec, USED_DOFS); + T value = value0; + for(vecIter.reset(); !vecIter.end(); ++vecIter) + { + value = (*binary_op)(value, *vecIter); + } + return value; +} + +template<typename TOut, typename T1, typename T2> +TOut accumulateDOF_simple(DOFVector<T1> *vec1, + DOFVector<T2> *vec2, + TOut value0, + TertiaryAbstractFunction<TOut, TOut, T1, T2> *tertiary_op) +{ + TEST_EXIT(vec1->getFeSpace() == vec2->getFeSpace())("FeSpaces must be equal!\n"); + DOFIterator<T1> vec1Iter(vec1, USED_DOFS); + DOFIterator<T2> vec2Iter(vec2, USED_DOFS); + TOut value = value0; + for(vec1Iter.reset(),vec2Iter.reset(); !vec1Iter.end(); ++vec1Iter,++vec2Iter) + { + value = (*tertiary_op)(value, *vec1Iter, *vec2Iter); + } + return value; +} + } #endif // AMDIS_TRANSFORM_DOF_H diff --git a/AMDiS/src/ZeroOrderTerm.cc b/AMDiS/src/ZeroOrderTerm.cc index c324829e2c732ee9ec76257cf19d60e623819d67..57d0276d7bed59417fec05a39e2a3cda8d534136 100644 --- a/AMDiS/src/ZeroOrderTerm.cc +++ b/AMDiS/src/ZeroOrderTerm.cc @@ -126,7 +126,10 @@ namespace AMDiS { Vec2AtQP_ZOT::Vec2AtQP_ZOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, BinaryAbstractFunction<double, double, double> *af) - : ZeroOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), f(af) + : ZeroOrderTerm((af ? af->getDegree() : dv1->getFeSpace()->getBasisFcts()->getDegree()+dv2->getFeSpace()->getBasisFcts()->getDegree())), + vec1(dv1), + vec2(dv2), + f(af) { TEST_EXIT(dv1)("No first vector!\n"); TEST_EXIT(dv2)("No second vector!\n"); @@ -156,9 +159,14 @@ namespace AMDiS { } void Vec2AtQP_ZOT::getC(const ElInfo *, int nPoints, ElementVector& C) - { - for (int iq = 0; iq < nPoints; iq++) - C[iq] += (*f)(vecAtQPs1[iq], vecAtQPs2[iq]); + { + if (f) { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += (*f)(vecAtQPs1[iq], vecAtQPs2[iq]); + } else { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += vecAtQPs1[iq] * vecAtQPs2[iq]; + } } void Vec2AtQP_ZOT::eval(int nPoints, @@ -168,8 +176,13 @@ namespace AMDiS { mtl::dense_vector<double>& result, double fac) { - for (int iq = 0; iq < nPoints; iq++) - result[iq] += fac * (*f)(vecAtQPs1[iq], vecAtQPs2[iq]) * uhAtQP[iq]; + if (f) { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += fac * (*f)(vecAtQPs1[iq], vecAtQPs2[iq]) * uhAtQP[iq]; + } else { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += fac * vecAtQPs1[iq] * vecAtQPs2[iq] * uhAtQP[iq]; + } } @@ -179,7 +192,13 @@ namespace AMDiS { DOFVectorBase<double> *dv2, DOFVectorBase<double> *dv3, TertiaryAbstractFunction<double, double, double, double> *af) - : ZeroOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), vec3(dv3), f(af) + : ZeroOrderTerm((af ? af->getDegree() : dv1->getFeSpace()->getBasisFcts()->getDegree() + + dv2->getFeSpace()->getBasisFcts()->getDegree() + + dv3->getFeSpace()->getBasisFcts()->getDegree())), + vec1(dv1), + vec2(dv2), + vec3(dv3), + f(af) { TEST_EXIT(dv1)("No first vector!\n"); TEST_EXIT(dv2)("No second vector!\n"); @@ -200,9 +219,14 @@ namespace AMDiS { } void Vec3AtQP_ZOT::getC(const ElInfo *, int nPoints, ElementVector& C) - { - for (int iq = 0; iq < nPoints; iq++) - C[iq] += (*f)(vecAtQPs1[iq], vecAtQPs2[iq], vecAtQPs3[iq]); + { + if (f) { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += (*f)(vecAtQPs1[iq], vecAtQPs2[iq], vecAtQPs3[iq]); + } else { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += vecAtQPs1[iq] * vecAtQPs2[iq] * vecAtQPs3[iq]; + } } void Vec3AtQP_ZOT::eval(int nPoints, @@ -212,9 +236,15 @@ namespace AMDiS { mtl::dense_vector<double>& result, double fac) { - for (int iq = 0; iq < nPoints; iq++) - result[iq] += - fac * (*f)(vecAtQPs1[iq], vecAtQPs2[iq], vecAtQPs3[iq]) * uhAtQP[iq]; + if (f) { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += + fac * (*f)(vecAtQPs1[iq], vecAtQPs2[iq], vecAtQPs3[iq]) * uhAtQP[iq]; + } else { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += + fac * vecAtQPs1[iq] * vecAtQPs2[iq] * vecAtQPs3[iq] * uhAtQP[iq]; + } } diff --git a/AMDiS/src/ZeroOrderTerm.h b/AMDiS/src/ZeroOrderTerm.h index 21231e8e9fc2a1d23c757e6e4bc0b31282b3348d..986cfd535d156cc498548b2197d7e00041ec0310 100644 --- a/AMDiS/src/ZeroOrderTerm.h +++ b/AMDiS/src/ZeroOrderTerm.h @@ -190,7 +190,7 @@ namespace AMDiS { /// Constructor. Vec2AtQP_ZOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, - BinaryAbstractFunction<double, double, double> *f); + BinaryAbstractFunction<double, double, double> *f = NULL); /// Implementation of \ref OperatorTerm::initElement(). void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, @@ -242,7 +242,7 @@ namespace AMDiS { Vec3AtQP_ZOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, DOFVectorBase<double> *dv3, - TertiaryAbstractFunction<double, double, double, double> *f); + TertiaryAbstractFunction<double, double, double, double> *f = NULL); /// Implementation of \ref OperatorTerm::initElement(). void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, diff --git a/AMDiS/src/io/ElementFileWriter.cc b/AMDiS/src/io/ElementFileWriter.cc index 6878a05f322f745d2bbd866d34d9d23a7869792b..e61d8800347b2da63c2fec3f23532427dab1380b 100644 --- a/AMDiS/src/io/ElementFileWriter.cc +++ b/AMDiS/src/io/ElementFileWriter.cc @@ -33,21 +33,27 @@ namespace AMDiS { : name(name_), amdisMeshDatExt(".elem.mesh"), vtkExt(".vtu"), + pvdExt(".pvd"), writeAMDiSFormat(0), writeVtkFormat(0), + writeVtkVectorFormat(0), + writeAs3dVector(true), + writeParaViewAnimation(0), appendIndex(0), indexLength(5), indexDecimals(3), tsModulo(1), timestepNumber(-1), mesh(mesh_), - vec(mapvec) + vec(&mapvec), + vecs(NULL) { if (name != "") { Parameters::get(name + "->output->filename", filename); Parameters::get(name + "->output->AMDiS format", writeAMDiSFormat); Parameters::get(name + "->output->AMDiS mesh-dat ext", amdisMeshDatExt); Parameters::get(name + "->output->ParaView format", writeVtkFormat); + Parameters::get(name + "->output->ParaView animation", writeParaViewAnimation); Parameters::get(name + "->output->append index", appendIndex); Parameters::get(name + "->output->index length", indexLength); Parameters::get(name + "->output->index decimals", indexDecimals); @@ -56,6 +62,43 @@ namespace AMDiS { } + ElementFileWriter::ElementFileWriter(string name_, + Mesh *mesh_, + map<int, vector<double> > &mapvec) + : name(name_), + amdisMeshDatExt(".elem.mesh"), + vtkExt(".vtu"), + pvdExt(".pvd"), + writeAMDiSFormat(0), + writeVtkFormat(0), + writeVtkVectorFormat(0), + writeAs3dVector(true), + writeParaViewAnimation(0), + appendIndex(0), + indexLength(5), + indexDecimals(3), + tsModulo(1), + timestepNumber(-1), + mesh(mesh_), + vec(NULL), + vecs(&mapvec) + { + if (name != "") { + Parameters::get(name + "->output->filename", filename); + Parameters::get(name + "->output->AMDiS format", writeAMDiSFormat); + Parameters::get(name + "->output->AMDiS mesh-dat ext", amdisMeshDatExt); + Parameters::get(name + "->output->ParaView format", writeVtkFormat); + Parameters::get(name + "->output->ParaView vector format", writeVtkVectorFormat); + Parameters::get(name + "->output->write vector as 3d vector", writeAs3dVector); + Parameters::get(name + "->output->ParaView animation", writeParaViewAnimation); + Parameters::get(name + "->output->append index", appendIndex); + Parameters::get(name + "->output->index length", indexLength); + Parameters::get(name + "->output->index decimals", indexDecimals); + Parameters::get(name + "->output->write every i-th timestep", tsModulo); + } + } + + void ElementFileWriter::writeFiles(AdaptInfo *adaptInfo, bool force, int level, Flag traverseFlag, bool (*writeElem)(ElInfo*)) @@ -92,12 +135,16 @@ namespace AMDiS { MSG("MeshDat file written to %s\n", (fn + amdisMeshDatExt).c_str()); } - if (writeVtkFormat) { + if (writeVtkFormat || writeVtkVectorFormat) { TEST_EXIT(mesh)("no mesh\n"); - writeVtkValues(fn, vtkExt); + writeVtkValues(fn, vtkExt,-1,writeVtkVectorFormat==1); MSG("VTK file written to %s\n", (fn + vtkExt).c_str()); } + + if (writeParaViewAnimation) { + VtkWriter::updateAnimationFile(adaptInfo, (fn + vtkExt), ¶ViewAnimationFrames, (filename + pvdExt)); + } } @@ -105,10 +152,23 @@ namespace AMDiS { Mesh *mesh, string filename, string postfix, - int level) + int level, + bool writeAsVector) { ElementFileWriter efw("", mesh, vec); - efw.writeVtkValues(filename, postfix, level); + efw.writeVtkValues(filename, postfix, level, writeAsVector); + } + + + void ElementFileWriter::writeFile(map<int, vector<double> > &vecs, + Mesh *mesh, + string filename, + string postfix, + int level, + bool writeAsVector) + { + ElementFileWriter efw("", mesh, vecs); + efw.writeVtkValues(filename, postfix, level, writeAsVector); } @@ -198,7 +258,7 @@ namespace AMDiS { while (elInfo) { // Get element value. - val = vec[elInfo->getElement()->getIndex()]; + val = (*vec)[elInfo->getElement()->getIndex()]; // Write value for each vertex of each element. for (int i = 0; i <= dim; ++i) { @@ -218,10 +278,13 @@ namespace AMDiS { void ElementFileWriter::writeVtkValues(string fname, string postfix, - int level) + int level, + bool writeAsVector) { FUNCNAME("ElementFileWriter::writeVtkValues()"); + TEST_EXIT((vec!=NULL || vecs!=NULL) && (vec==NULL || vecs==NULL))("Ether vec or vecs must be given, not both and not nothing!"); + #if HAVE_PARALLEL_DOMAIN_AMDIS string filename = fname + @@ -242,49 +305,47 @@ namespace AMDiS { file.push(boost::iostreams::file_descriptor_sink(filename, ios::trunc)); int dim = mesh->getDim(); - int dimOfWorld = Global::getGeo(WORLD); int vertices = mesh->getGeo(VERTEX); - int nElements = mesh->getNumberOfLeaves(); + int nVertices = 0; + int nElements = 0; Flag traverseFlag = level == -1 ? Mesh::CALL_LEAF_EL : Mesh::CALL_EL_LEVEL; - if (level != -1) { - nElements = 0; + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh, level, traverseFlag); + while (elInfo) { + nElements++; + elInfo = stack.traverseNext(elInfo); + } - TraverseStack stack; - ElInfo *elInfo = stack.traverseFirst(mesh, level, Mesh::CALL_EL_LEVEL); - while (elInfo) { - nElements++; - elInfo = stack.traverseNext(elInfo); + // === Write vertex coordinates (every vertex for every element). === + elInfo = stack.traverseFirst(mesh, level, traverseFlag | Mesh::FILL_COORDS); + + std::map<DegreeOfFreedom, std::pair<int, WorldVector<double> > > dof2Idx; + std::vector<DegreeOfFreedom> idx2Dof; + while (elInfo) { + // Write coordinates of all element vertices. + for (int i = 0; i <= dim; i++) { + DegreeOfFreedom idx = elInfo->getElement()->getDof(i, 0); + if (dof2Idx.find(idx) == dof2Idx.end()) { + dof2Idx[idx] = std::make_pair(nVertices, elInfo->getCoord(i)); + idx2Dof.push_back(idx); + nVertices++; + } } + elInfo = stack.traverseNext(elInfo); } file << "<?xml version=\"1.0\"?>\n"; file << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n"; file << " <UnstructuredGrid>\n"; - file << " <Piece NumberOfPoints=\"" << (dim + 1) * nElements + file << " <Piece NumberOfPoints=\"" << nVertices << "\" NumberOfCells=\"" << nElements << "\">\n"; file << " <Points>\n"; file << " <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">\n"; - - // === Write vertex coordinates (every vertex for every element). === - TraverseStack stack; - ElInfo *elInfo = - stack.traverseFirst(mesh, level, traverseFlag | Mesh::FILL_COORDS); - - while (elInfo) { - // Write coordinates of all element vertices. - for (int i = 0; i <= dim; i++) { - for (int j = 0; j < dimOfWorld; j++) - file << elInfo->getCoord(i)[j] << " "; - - for (int j = dimOfWorld; j < 3; j++) - file << "0.0"; - - file << "\n"; - } - - elInfo = stack.traverseNext(elInfo); + for (int i = 0; i < nVertices; i++) { + DegreeOfFreedom dof = idx2Dof[i]; + writeCoord(file, dof2Idx[dof].second); } file << " </DataArray>\n"; @@ -316,40 +377,60 @@ namespace AMDiS { file << " </DataArray>\n"; file << " <DataArray type=\"Int32\" Name=\"connectivity\">\n"; - int vertCntr = 0; - for (int i = 0; i < nElements; ++i) { - for (int j = 0; j <= dim; ++j) { - file << vertCntr << " "; - ++vertCntr; + elInfo = stack.traverseFirst(mesh, level, traverseFlag); + while (elInfo) { + // Write coordinates of all element vertices. + for (int i = 0; i <= dim; i++) { + DegreeOfFreedom dof = elInfo->getElement()->getDof(i, 0); + file << (dof2Idx[dof].first) << " "; } file << "\n"; + elInfo = stack.traverseNext(elInfo); } file << " </DataArray>\n"; - file << " </Cells>\n"; - file << " <PointData>\n"; - file << " <DataArray type=\"Float32\" Name=\"value\" format=\"ascii\">\n"; - file.setf(ios::scientific,ios::floatfield); + int dataLength = (vecs != NULL ? (*(vecs->begin())).second.size() : 1); + int nComponents = (!writeAsVector || (vecs == NULL && vec != NULL) ? 1 : dataLength); + int nDataArrays = (!writeAsVector && (vec == NULL && vecs != NULL) ? dataLength : 1); + file << " <CellData>\n"; + for (int i = 0; i < nDataArrays; i++) { + file << " <DataArray type=\"Float32\" Name=\"value"<<i<<"\" format=\"ascii\" NumberOfComponents=\""<<(writeAsVector ? std::max(3,nComponents) : nComponents)<<"\">\n"; - elInfo = stack.traverseFirst(mesh, level, traverseFlag | Mesh::FILL_COORDS); - int vc = 0; - while (elInfo) { - // Get element value. - double val = vec[elInfo->getElement()->getIndex()]; - - // Write value for each vertex of each element. - for (int i = 0; i <= dim; i++) - file << (fabs(val) < 1e-40 ? 0.0 : val) << "\n"; - - vc++; - elInfo = stack.traverseNext(elInfo); - } + file.setf(ios::scientific,ios::floatfield); - file << " </DataArray>\n"; - + elInfo = stack.traverseFirst(mesh, level, traverseFlag); + int vc = 0; + while (elInfo) { + // Get element value. + int idx = elInfo->getElement()->getIndex(); + + for (int j = 0; j < nComponents; j++) { + double val = (vec != NULL ? (*vec)[idx] : ((*vecs)[idx].size()==dataLength ? (*vecs)[idx][i*nComponents+j] : 0.0)); + + // Write value for each vertex of each element. + if (fabs(val) < 1.e-40) + file << "0.0"; + else + file << val; - file << " </PointData>\n"; + if (j < nComponents-1) + file << " "; + } + if (writeAs3dVector && writeAsVector && vecs != NULL) { + for (int j = nComponents; j < 3; j++) + file << " 0.0"; + } + file << "\n"; + + vc++; + elInfo = stack.traverseNext(elInfo); + } + + file << " </DataArray>\n"; + } + + file << " </CellData>\n"; file << " </Piece>\n"; file << " </UnstructuredGrid>\n"; file << "</VTKFile>\n"; @@ -361,3 +442,5 @@ namespace AMDiS { #endif } } + + diff --git a/AMDiS/src/io/ElementFileWriter.h b/AMDiS/src/io/ElementFileWriter.h index e8915b1a14f4bc30873ee054d1017ceb0e6766fd..e678ab8d3073735336513b35e21a1161711528f9 100644 --- a/AMDiS/src/io/ElementFileWriter.h +++ b/AMDiS/src/io/ElementFileWriter.h @@ -48,6 +48,10 @@ namespace AMDiS { ElementFileWriter(string name, Mesh *mesh, map<int, double> &vec); + + ElementFileWriter(string name, + Mesh *mesh, + map<int, vector<double> > &vecs); /// Implementation of FileWriterInterface::writeFiles(). void writeFiles(AdaptInfo *adaptInfo, bool force, @@ -60,7 +64,15 @@ namespace AMDiS { Mesh *mesh, string filename, string postfix = ".vtu", - int level = -1); + int level = -1, + bool writeAsVector = false); + + static void writeFile(map<int, vector<double> > &vecs, + Mesh *mesh, + string filename, + string postfix = ".vtu", + int level = -1, + bool writeAsVector = true); protected: /// Writes element data in AMDiS format (1 file !). @@ -68,8 +80,20 @@ namespace AMDiS { /// Writes element data in VTK format. void writeVtkValues(string filename, string postfix, - int level = -1); - + int level = -1, bool writeAsVector = false); + + /// Writes a world coordinate to a given file. + template<typename T> + void writeCoord(T &file, WorldVector<double> coord) + { + for (int i = 0; i < Global::getGeo(WORLD); i++) + file << " " << std::scientific << coord[i]; + for (int i = Global::getGeo(WORLD); i < 3; i++) + file << " " << "0.0"; + + file << "\n"; + } + protected: /// Name. string name; @@ -82,6 +106,7 @@ namespace AMDiS { /// VTK file extension. string vtkExt; + string pvdExt; /// 0: Don't write AMDiS files. /// 1: Write AMDiS files. @@ -90,7 +115,12 @@ namespace AMDiS { /// 0: Don't write VTK files. /// 1: Write VTK files. int writeVtkFormat; + int writeVtkVectorFormat; + bool writeAs3dVector; + + int writeParaViewAnimation; + /// 0: Don't append time index to filename prefix. /// 1: Append time index to filename prefix. int appendIndex; @@ -111,7 +141,10 @@ namespace AMDiS { Mesh *mesh; /// Vector that stores the solution. - map<int, double> vec; + map<int, double> *vec; + map<int, vector<double> > *vecs; + + vector< pair<double, string> > paraViewAnimationFrames; }; }