From a547037e6f2c3e1e1ab9469d72a5cd08585003da Mon Sep 17 00:00:00 2001 From: Thomas Witkowski <thomas.witkowski@gmx.de> Date: Wed, 31 Mar 2010 10:51:33 +0000 Subject: [PATCH] New source code structure for operators. --- AMDiS/bin/Makefile.am | 4 + AMDiS/bin/Makefile.in | 50 +- AMDiS/src/AMDiS.h | 4 + AMDiS/src/FirstOrderTerm.cc | 804 +++++++++ AMDiS/src/FirstOrderTerm.h | 770 +++++++++ AMDiS/src/Operator.cc | 3085 +--------------------------------- AMDiS/src/Operator.h | 3053 +-------------------------------- AMDiS/src/OperatorTerm.cc | 183 ++ AMDiS/src/OperatorTerm.h | 274 +++ AMDiS/src/SecondOrderTerm.cc | 1235 ++++++++++++++ AMDiS/src/SecondOrderTerm.h | 1190 +++++++++++++ AMDiS/src/ZeroOrderTerm.cc | 1026 +++++++++++ AMDiS/src/ZeroOrderTerm.h | 959 +++++++++++ 13 files changed, 6505 insertions(+), 6132 deletions(-) create mode 100644 AMDiS/src/FirstOrderTerm.cc create mode 100644 AMDiS/src/FirstOrderTerm.h create mode 100644 AMDiS/src/OperatorTerm.cc create mode 100644 AMDiS/src/OperatorTerm.h create mode 100644 AMDiS/src/SecondOrderTerm.cc create mode 100644 AMDiS/src/SecondOrderTerm.h create mode 100644 AMDiS/src/ZeroOrderTerm.cc create mode 100644 AMDiS/src/ZeroOrderTerm.h diff --git a/AMDiS/bin/Makefile.am b/AMDiS/bin/Makefile.am index 2e236da8..e5ff870b 100644 --- a/AMDiS/bin/Makefile.am +++ b/AMDiS/bin/Makefile.am @@ -120,6 +120,10 @@ $(SOURCE_DIR)/FileWriter.h $(SOURCE_DIR)/FileWriter.hh $(SOURCE_DIR)/FileWriter. $(SOURCE_DIR)/ElementFileWriter.h $(SOURCE_DIR)/ElementFileWriter.cc \ $(SOURCE_DIR)/ElInfo.cc \ $(SOURCE_DIR)/ElInfoStack.h $(SOURCE_DIR)/ElInfoStack.cc \ +$(SOURCE_DIR)/OperatorTerm.h $(SOURCE_DIR)/OperatorTerm.cc \ +$(SOURCE_DIR)/ZeroOrderTerm.h $(SOURCE_DIR)/ZeroOrderTerm.cc \ +$(SOURCE_DIR)/FirstOrderTerm.h $(SOURCE_DIR)/FirstOrderTerm.cc \ +$(SOURCE_DIR)/SecondOrderTerm.h $(SOURCE_DIR)/SecondOrderTerm.cc \ $(SOURCE_DIR)/Operator.h $(SOURCE_DIR)/Operator.cc \ $(SOURCE_DIR)/Mesh.cc \ $(SOURCE_DIR)/MeshStructure.h $(SOURCE_DIR)/MeshStructure.cc \ diff --git a/AMDiS/bin/Makefile.in b/AMDiS/bin/Makefile.in index 85841a9f..7580d8fa 100644 --- a/AMDiS/bin/Makefile.in +++ b/AMDiS/bin/Makefile.in @@ -154,9 +154,13 @@ am__libamdis_la_SOURCES_DIST = $(SOURCE_DIR)/parallel/StdMpi.h \ $(SOURCE_DIR)/FileWriter.cc $(SOURCE_DIR)/ElementFileWriter.h \ $(SOURCE_DIR)/ElementFileWriter.cc $(SOURCE_DIR)/ElInfo.cc \ $(SOURCE_DIR)/ElInfoStack.h $(SOURCE_DIR)/ElInfoStack.cc \ - $(SOURCE_DIR)/Operator.h $(SOURCE_DIR)/Operator.cc \ - $(SOURCE_DIR)/Mesh.cc $(SOURCE_DIR)/MeshStructure.h \ - $(SOURCE_DIR)/MeshStructure.cc \ + $(SOURCE_DIR)/OperatorTerm.h $(SOURCE_DIR)/OperatorTerm.cc \ + $(SOURCE_DIR)/ZeroOrderTerm.h $(SOURCE_DIR)/ZeroOrderTerm.cc \ + $(SOURCE_DIR)/FirstOrderTerm.h $(SOURCE_DIR)/FirstOrderTerm.cc \ + $(SOURCE_DIR)/SecondOrderTerm.h \ + $(SOURCE_DIR)/SecondOrderTerm.cc $(SOURCE_DIR)/Operator.h \ + $(SOURCE_DIR)/Operator.cc $(SOURCE_DIR)/Mesh.cc \ + $(SOURCE_DIR)/MeshStructure.h $(SOURCE_DIR)/MeshStructure.cc \ $(SOURCE_DIR)/MeshStructure_ED.h $(SOURCE_DIR)/AMDiS.h \ $(SOURCE_DIR)/AdaptStationary.h \ $(SOURCE_DIR)/AdaptStationary.cc \ @@ -271,7 +275,9 @@ am_libamdis_la_OBJECTS = $(am__objects_2) libamdis_la-DOFIndexed.lo \ libamdis_la-BoundaryManager.lo libamdis_la-DirichletBC.lo \ libamdis_la-RobinBC.lo libamdis_la-FileWriter.lo \ libamdis_la-ElementFileWriter.lo libamdis_la-ElInfo.lo \ - libamdis_la-ElInfoStack.lo libamdis_la-Operator.lo \ + libamdis_la-ElInfoStack.lo libamdis_la-OperatorTerm.lo \ + libamdis_la-ZeroOrderTerm.lo libamdis_la-FirstOrderTerm.lo \ + libamdis_la-SecondOrderTerm.lo libamdis_la-Operator.lo \ libamdis_la-Mesh.lo libamdis_la-MeshStructure.lo \ libamdis_la-AdaptStationary.lo \ libamdis_la-AdaptInstationary.lo libamdis_la-DOFVector.lo \ @@ -541,6 +547,10 @@ $(SOURCE_DIR)/FileWriter.h $(SOURCE_DIR)/FileWriter.hh $(SOURCE_DIR)/FileWriter. $(SOURCE_DIR)/ElementFileWriter.h $(SOURCE_DIR)/ElementFileWriter.cc \ $(SOURCE_DIR)/ElInfo.cc \ $(SOURCE_DIR)/ElInfoStack.h $(SOURCE_DIR)/ElInfoStack.cc \ +$(SOURCE_DIR)/OperatorTerm.h $(SOURCE_DIR)/OperatorTerm.cc \ +$(SOURCE_DIR)/ZeroOrderTerm.h $(SOURCE_DIR)/ZeroOrderTerm.cc \ +$(SOURCE_DIR)/FirstOrderTerm.h $(SOURCE_DIR)/FirstOrderTerm.cc \ +$(SOURCE_DIR)/SecondOrderTerm.h $(SOURCE_DIR)/SecondOrderTerm.cc \ $(SOURCE_DIR)/Operator.h $(SOURCE_DIR)/Operator.cc \ $(SOURCE_DIR)/Mesh.cc \ $(SOURCE_DIR)/MeshStructure.h $(SOURCE_DIR)/MeshStructure.cc \ @@ -772,6 +782,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-FileWriter.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-FiniteElemSpace.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-FirstOrderAssembler.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-FirstOrderTerm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-FixVec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-GNUPlotWriter.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Global.Plo@am__quote@ @@ -789,6 +800,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-MpiHelper.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-NonLinUpdater.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Operator.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-OperatorTerm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ParMetisPartitioner.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ParallelDomainBase.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ParallelDomainDbg.Plo@am__quote@ @@ -820,6 +832,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-RobinBC.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ScalableQuadrature.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-SecondOrderAssembler.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-SecondOrderTerm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-StandardProblemIteration.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-StdMpi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-SubAssembler.Plo@am__quote@ @@ -835,6 +848,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-VertexVector.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-VtkWriter.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ZeroOrderAssembler.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ZeroOrderTerm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcompositeFEM_la-CFE_Integration.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcompositeFEM_la-CFE_NormAndErrorFcts.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcompositeFEM_la-CompositeFEMMethods.Plo@am__quote@ @@ -1202,6 +1216,34 @@ libamdis_la-ElInfoStack.lo: $(SOURCE_DIR)/ElInfoStack.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ElInfoStack.lo `test -f '$(SOURCE_DIR)/ElInfoStack.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ElInfoStack.cc +libamdis_la-OperatorTerm.lo: $(SOURCE_DIR)/OperatorTerm.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-OperatorTerm.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-OperatorTerm.Tpo" -c -o libamdis_la-OperatorTerm.lo `test -f '$(SOURCE_DIR)/OperatorTerm.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/OperatorTerm.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-OperatorTerm.Tpo" "$(DEPDIR)/libamdis_la-OperatorTerm.Plo"; else rm -f "$(DEPDIR)/libamdis_la-OperatorTerm.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/OperatorTerm.cc' object='libamdis_la-OperatorTerm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-OperatorTerm.lo `test -f '$(SOURCE_DIR)/OperatorTerm.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/OperatorTerm.cc + +libamdis_la-ZeroOrderTerm.lo: $(SOURCE_DIR)/ZeroOrderTerm.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ZeroOrderTerm.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ZeroOrderTerm.Tpo" -c -o libamdis_la-ZeroOrderTerm.lo `test -f '$(SOURCE_DIR)/ZeroOrderTerm.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ZeroOrderTerm.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ZeroOrderTerm.Tpo" "$(DEPDIR)/libamdis_la-ZeroOrderTerm.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ZeroOrderTerm.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/ZeroOrderTerm.cc' object='libamdis_la-ZeroOrderTerm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ZeroOrderTerm.lo `test -f '$(SOURCE_DIR)/ZeroOrderTerm.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ZeroOrderTerm.cc + +libamdis_la-FirstOrderTerm.lo: $(SOURCE_DIR)/FirstOrderTerm.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-FirstOrderTerm.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-FirstOrderTerm.Tpo" -c -o libamdis_la-FirstOrderTerm.lo `test -f '$(SOURCE_DIR)/FirstOrderTerm.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/FirstOrderTerm.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-FirstOrderTerm.Tpo" "$(DEPDIR)/libamdis_la-FirstOrderTerm.Plo"; else rm -f "$(DEPDIR)/libamdis_la-FirstOrderTerm.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/FirstOrderTerm.cc' object='libamdis_la-FirstOrderTerm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-FirstOrderTerm.lo `test -f '$(SOURCE_DIR)/FirstOrderTerm.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/FirstOrderTerm.cc + +libamdis_la-SecondOrderTerm.lo: $(SOURCE_DIR)/SecondOrderTerm.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-SecondOrderTerm.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-SecondOrderTerm.Tpo" -c -o libamdis_la-SecondOrderTerm.lo `test -f '$(SOURCE_DIR)/SecondOrderTerm.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/SecondOrderTerm.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-SecondOrderTerm.Tpo" "$(DEPDIR)/libamdis_la-SecondOrderTerm.Plo"; else rm -f "$(DEPDIR)/libamdis_la-SecondOrderTerm.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/SecondOrderTerm.cc' object='libamdis_la-SecondOrderTerm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-SecondOrderTerm.lo `test -f '$(SOURCE_DIR)/SecondOrderTerm.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/SecondOrderTerm.cc + libamdis_la-Operator.lo: $(SOURCE_DIR)/Operator.cc @am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-Operator.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-Operator.Tpo" -c -o libamdis_la-Operator.lo `test -f '$(SOURCE_DIR)/Operator.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/Operator.cc; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-Operator.Tpo" "$(DEPDIR)/libamdis_la-Operator.Plo"; else rm -f "$(DEPDIR)/libamdis_la-Operator.Tpo"; exit 1; fi diff --git a/AMDiS/src/AMDiS.h b/AMDiS/src/AMDiS.h index e051f003..9d54f2ef 100644 --- a/AMDiS/src/AMDiS.h +++ b/AMDiS/src/AMDiS.h @@ -35,6 +35,7 @@ #include "Estimator.h" #include "FileWriter.h" #include "FiniteElemSpace.h" +#include "FirstOrderTerm.h" #include "FixVec.h" #include "Flag.h" #include "Global.h" @@ -57,6 +58,7 @@ #include "NonLinUpdater.h" #include "OEMSolver.h" #include "Operator.h" +#include "OperatorTerm.h" #include "Parameters.h" #include "Parametric.h" #include "PartitionElementData.h" @@ -71,6 +73,7 @@ #include "ProblemInterpolScal.h" #include "ProblemNonLin.h" #include "ProblemStatBase.h" +#include "SecondOrderTerm.h" #include "StandardProblemIteration.h" #include "Projection.h" #include "QPsiPhi.h" @@ -92,6 +95,7 @@ #include "Triangle.h" #include "ValueWriter.h" #include "VtkWriter.h" +#include "ZeroOrderTerm.h" #if HAVE_PARALLEL_DOMAIN_AMDIS #include "parallel/InteriorBoundary.h" diff --git a/AMDiS/src/FirstOrderTerm.cc b/AMDiS/src/FirstOrderTerm.cc new file mode 100644 index 00000000..d8680438 --- /dev/null +++ b/AMDiS/src/FirstOrderTerm.cc @@ -0,0 +1,804 @@ +#include "FirstOrderTerm.h" +#include "DOFVector.h" + +namespace AMDiS { + + // =========== VecAtQP_FOT ========== + + VecAtQP_FOT::VecAtQP_FOT(DOFVectorBase<double> *dv, + AbstractFunction<double, double> *af, + WorldVector<double> *wv) + : FirstOrderTerm(af->getDegree()), vec(dv), f(af), b(wv) + { + TEST_EXIT(dv)("No vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + } + + VecAtQP_FOT::VecAtQP_FOT(DOFVectorBase<double> *dv, + AbstractFunction<double, double> *af, + int bIdx) + : FirstOrderTerm(af->getDegree()), vec(dv), f(af) + { + TEST_EXIT(dv)("No vector!\n"); + + bOne = bIdx; + auxFeSpaces.insert(dv->getFESpace()); + } + + void VecAtQP_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); + } + + void VecAtQP_FOT::getLb(const ElInfo *elInfo, int nPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + + if (bOne > -1) { + for (int iq = 0; iq < nPoints; iq++) + lb_one(Lambda, Lb[iq], (*f)(vecAtQPs[iq])); + } else if (b) { + for (int iq = 0; iq < nPoints; iq++) + lb(Lambda, *b, Lb[iq], (*f)(vecAtQPs[iq])); + } else { + for (int iq = 0; iq < nPoints; iq++) + l1(Lambda, Lb[iq], (*f)(vecAtQPs[iq])); + } + } + + void VecAtQP_FOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + int dow = Global::getGeo(WORLD); + + if (grdUhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*f)(vecAtQPs[iq]); + double resultQP = 0.0; + for (int i = 0; i < dow; i++) + resultQP += grdUhAtQP[iq][i]; + result[iq] += fac * factor * resultQP; + } + } + } + + + // =========== CoordsAtQP_FOT =========== + + void CoordsAtQP_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void CoordsAtQP_FOT::getLb(const ElInfo *elInfo, int nPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + l1(Lambda, Lb[iq], (*g)(coordsAtQPs[iq])); + } + + void CoordsAtQP_FOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double f) + { + int dow = Global::getGeo(WORLD); + + if (grdUhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*g)(coordsAtQPs[iq]); + double resultQP = 0.0; + for (int i = 0; i < dow; i++) + resultQP += grdUhAtQP[iq][i]; + result[iq] += f * factor * resultQP; + } + } + } + + + // ========== VecCoordsAtQP_FOT ========== + + void VecCoordsAtQP_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void VecCoordsAtQP_FOT::getLb(const ElInfo *elInfo, int nPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + lb(Lambda, b, Lb[iq], (*g)(coordsAtQPs[iq])); + } + + void VecCoordsAtQP_FOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double f) + { + int dow = Global::getGeo(WORLD); + + if (grdUhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*g)(coordsAtQPs[iq]); + double resultQP = 0.0; + for (int i = 0; i < dow; i++) + resultQP += grdUhAtQP[iq][i]; + + result[iq] += f * factor * resultQP; + } + } + } + + + // ========== VectorGradient_FOT ========== + + VectorGradient_FOT::VectorGradient_FOT(DOFVectorBase<double> *dv, + AbstractFunction<WorldVector<double>, WorldVector<double> > *af) + : FirstOrderTerm(af->getDegree()), vec(dv), f(af) + { + TEST_EXIT(dv)("No vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + } + + void VectorGradient_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); + } + + void VectorGradient_FOT::getLb(const ElInfo *elInfo, int nPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + if (f) { + for (int iq = 0; iq < nPoints; iq++) + lb(Lambda, (*f)(gradAtQPs[iq]), Lb[iq], 1.0); + } else { + for (int iq = 0; iq < nPoints; iq++) + lb(Lambda, gradAtQPs[iq], Lb[iq], 1.0); + } + } + + void VectorGradient_FOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) + { + if (grdUhAtQP) { + if (f) { + for (int iq = 0; iq < nPoints; iq++) { + WorldVector<double> b = (*f)(gradAtQPs[iq]); + result[iq] += b * grdUhAtQP[iq] * factor; + } + } else { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += gradAtQPs[iq] * grdUhAtQP[iq] * factor; + } + } + } + + + // =========== VectorFct_FOT ========== + + VectorFct_FOT::VectorFct_FOT(DOFVectorBase<double> *dv, + AbstractFunction<WorldVector<double>, double> *fct) + : FirstOrderTerm(fct->getDegree()), vec(dv), vecFct(fct) + { + TEST_EXIT(dv)("No vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + } + + void VectorFct_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); + } + + void VectorFct_FOT::getLb(const ElInfo *elInfo, int nPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + lb(Lambda, (*vecFct)(vecAtQPs[iq]), Lb[iq], 1.0); + } + + void VectorFct_FOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) + { + if (grdUhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + WorldVector<double> b = (*vecFct)(vecAtQPs[iq]); + result[iq] += b * grdUhAtQP[iq] * factor; + } + } + } + + + // =========== VecFctAtQP_FOT ========== + + void VecFctAtQP_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + + void VecFctAtQP_FOT::getLb(const ElInfo *elInfo, int nPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + lb(Lambda, (*g)(coordsAtQPs[iq]), Lb[iq], 1.0); + } + + void VecFctAtQP_FOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double f) + { + int dow = Global::getGeo(WORLD); + + if (grdUhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + double resultQP = 0.0; + const WorldVector<double> &b = (*g)(coordsAtQPs[iq]); + for (int i = 0; i < dow; i++) + resultQP += b[i] * grdUhAtQP[iq][i]; + result[iq] += f * resultQP; + } + } + } + + + // =========== VecGrad_FOT =========== + + VecGrad_FOT::VecGrad_FOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, + BinaryAbstractFunction<WorldVector<double>, double, WorldVector<double> > *fct) + : FirstOrderTerm(fct->getDegree()), vec1(dv1), vec2(dv2), vecFct(fct) + { + TEST_EXIT(dv1)("No first vector!\n"); + TEST_EXIT(dv2)("No second vector!\n"); + + auxFeSpaces.insert(dv1->getFESpace()); + auxFeSpaces.insert(dv2->getFESpace()); + } + + void VecGrad_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = getVectorAtQPs(vec1, elInfo, subAssembler, quad); + gradAtQPs = getGradientsAtQPs(vec2, elInfo, subAssembler, quad); + } + + void VecGrad_FOT::initElement(const ElInfo* smallElInfo, + const ElInfo* largeElInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = getVectorAtQPs(vec1, smallElInfo, largeElInfo, subAssembler, quad); + gradAtQPs = getGradientsAtQPs(vec2, smallElInfo, largeElInfo, subAssembler, quad); + } + + void VecGrad_FOT::getLb(const ElInfo *elInfo, int nPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + lb(Lambda, (*vecFct)(vecAtQPs[iq], gradAtQPs[iq]), Lb[iq], 1.0); + } + + void VecGrad_FOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) + { + if (grdUhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + WorldVector<double> b = (*vecFct)(vecAtQPs[iq], gradAtQPs[iq]); + result[iq] += b * grdUhAtQP[iq] * factor; + } + } + } + + + // =========== FctGrad2_FOT =========== + + void FctGrad2_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + grad1AtQPs = subAssembler->getGradientsAtQPs(vec1, elInfo, quad); + grad2AtQPs = subAssembler->getGradientsAtQPs(vec2, elInfo, quad); + } + + void FctGrad2_FOT::getLb(const ElInfo *elInfo, int nPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + lb(Lambda, (*vecFct)(grad1AtQPs[iq], grad2AtQPs[iq]), Lb[iq], 1.0); + } + + void FctGrad2_FOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) + { + if (grdUhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + WorldVector<double> b = (*vecFct)(grad1AtQPs[iq], grad2AtQPs[iq]); + result[iq] += b * grdUhAtQP[iq] * factor; + } + } + } + + + // ========== Vec2AndGradAtQP_FOT ========== + + Vec2AndGradAtQP_FOT::Vec2AndGradAtQP_FOT(DOFVectorBase<double> *dv1, + DOFVectorBase<double> *dv2, + TertiaryAbstractFunction<double, double, double, WorldVector<double> > *f_, WorldVector<double> *b_) + : FirstOrderTerm(f_->getDegree()), + vec1(dv1), + vec2(dv2), + f(f_), + b(b_) + { + auxFeSpaces.insert(dv1->getFESpace()); + auxFeSpaces.insert(dv2->getFESpace()); + } + + void Vec2AndGradAtQP_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vec1AtQPs = subAssembler->getVectorAtQPs(vec1, elInfo, quad); + vec2AtQPs = subAssembler->getVectorAtQPs(vec2, elInfo, quad); + gradAtQPs1 = getGradientsAtQPs(vec1, elInfo, subAssembler, quad); + } + + void Vec2AndGradAtQP_FOT::getLb(const ElInfo *elInfo, int nPoints, VectorOfFixVecs<DimVec<double> >& Lb) const { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) { + if (b) + lb(Lambda, *b, Lb[iq], (*f)(vec1AtQPs[iq], vec2AtQPs[iq],gradAtQPs1[iq])); + else + l1(Lambda, Lb[iq], (*f)(vec1AtQPs[iq], vec2AtQPs[iq], gradAtQPs1[iq])); + } + } + + void Vec2AndGradAtQP_FOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + if (grdUhAtQP) + for (int iq = 0; iq < nPoints; iq++) + result[iq] += fac * + (*f)(vec1AtQPs[iq], vec2AtQPs[iq], gradAtQPs1[iq]) * + ((*b) * grdUhAtQP[iq]); + } + + + // ========== FctVecAtQP_FOT ========== + + + FctVecAtQP_FOT::FctVecAtQP_FOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<double, WorldVector<double>, double> *f_, + WorldVector<double> *b_) + : FirstOrderTerm(f_->getDegree()), vec(dv), f(f_), b(b_) + { + auxFeSpaces.insert(dv->getFESpace()); + } + + void FctVecAtQP_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void FctVecAtQP_FOT::getLb(const ElInfo *elInfo, int nPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) { + if (b) + lb(Lambda, *b, Lb[iq], (*f)(coordsAtQPs[iq], vecAtQPs[iq])); + else + l1(Lambda, Lb[iq], (*f)(coordsAtQPs[iq], vecAtQPs[iq])); + } + } + + void FctVecAtQP_FOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + if (grdUhAtQP) + for (int iq = 0; iq < nPoints; iq++) + result[iq] += + fac * (*f)(coordsAtQPs[iq], vecAtQPs[iq]) * ((*b) * grdUhAtQP[iq]); + } + + + // ========== Vec2AtQP_FOT ========== + + Vec2AtQP_FOT::Vec2AtQP_FOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, + BinaryAbstractFunction<double, double, double> *af, + WorldVector<double> *b_) + : FirstOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), f(af), b(b_) + { + TEST_EXIT(dv1)("No first vector!\n"); + TEST_EXIT(dv2)("No second vector!\n"); + + auxFeSpaces.insert(dv1->getFESpace()); + auxFeSpaces.insert(dv2->getFESpace()); + } + + Vec2AtQP_FOT::Vec2AtQP_FOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, + BinaryAbstractFunction<double, double, double> *af, + int bIdx) + : FirstOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), f(af) + { + TEST_EXIT(dv1)("No first vector!\n"); + TEST_EXIT(dv2)("No second vector!\n"); + + bOne = bIdx; + auxFeSpaces.insert(dv1->getFESpace()); + auxFeSpaces.insert(dv2->getFESpace()); + } + + void Vec2AtQP_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vec1AtQPs = subAssembler->getVectorAtQPs(vec1, elInfo, quad); + vec2AtQPs = subAssembler->getVectorAtQPs(vec2, elInfo, quad); + } + + void Vec2AtQP_FOT::getLb(const ElInfo *elInfo, int nPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + + if (bOne > -1) { + for (int iq = 0; iq < nPoints; iq++) + lb_one(Lambda, Lb[iq], (*f)(vec1AtQPs[iq], vec2AtQPs[iq])); + } else if (b) { + for (int iq = 0; iq < nPoints; iq++) + lb(Lambda, *b, Lb[iq], (*f)(vec1AtQPs[iq], vec2AtQPs[iq])); + } else { + for (int iq = 0; iq < nPoints; iq++) + l1(Lambda, Lb[iq], (*f)(vec1AtQPs[iq], vec2AtQPs[iq])); + } + } + + void Vec2AtQP_FOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + if (grdUhAtQP) + for (int iq = 0; iq < nPoints; iq++) + result[iq] += fac * (*f)(vec1AtQPs[iq], vec2AtQPs[iq]) * ((*b) * grdUhAtQP[iq]); + } + + + // ========== Vec3FctAtQP_FOT ========== + + Vec3FctAtQP_FOT::Vec3FctAtQP_FOT(DOFVectorBase<double> *dv1, + DOFVectorBase<double> *dv2, + DOFVectorBase<double> *dv3, + TertiaryAbstractFunction<double, double, double, double> *f_, + WorldVector<double> *bvec) + : FirstOrderTerm(f_->getDegree()), + vec1(dv1), + vec2(dv2), + vec3(dv3), + f(f_), + b(bvec) + { + auxFeSpaces.insert(dv1->getFESpace()); + auxFeSpaces.insert(dv2->getFESpace()); + auxFeSpaces.insert(dv3->getFESpace()); + } + + Vec3FctAtQP_FOT::Vec3FctAtQP_FOT(DOFVectorBase<double> *dv1, + DOFVectorBase<double> *dv2, + DOFVectorBase<double> *dv3, + TertiaryAbstractFunction<double, double, double, double> *f_, + int b) + : FirstOrderTerm(f_->getDegree()), + vec1(dv1), + vec2(dv2), + vec3(dv3), + f(f_) + { + bOne = b; + auxFeSpaces.insert(dv1->getFESpace()); + auxFeSpaces.insert(dv2->getFESpace()); + auxFeSpaces.insert(dv3->getFESpace()); + } + + void Vec3FctAtQP_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vec1AtQPs = subAssembler->getVectorAtQPs(vec1, elInfo, quad); + vec2AtQPs = subAssembler->getVectorAtQPs(vec2, elInfo, quad); + vec3AtQPs = subAssembler->getVectorAtQPs(vec3, elInfo, quad); + } + + void Vec3FctAtQP_FOT::getLb(const ElInfo *elInfo, int nPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + if (bOne > -1) { + for (int iq = 0; iq < nPoints; iq++) + lb_one(Lambda, Lb[iq], (*f)(vec1AtQPs[iq], vec2AtQPs[iq], vec3AtQPs[iq])); + } else { + for (int iq = 0; iq < nPoints; iq++) { + if (b) + lb(Lambda, *b, Lb[iq], (*f)(vec1AtQPs[iq], vec2AtQPs[iq], vec3AtQPs[iq])); + else + l1(Lambda, Lb[iq], (*f)(vec1AtQPs[iq], vec2AtQPs[iq], vec3AtQPs[iq])); + } + } + } + + void Vec3FctAtQP_FOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + if (grdUhAtQP) + for (int iq = 0; iq < nPoints; iq++) + result[iq] += fac * (*f)(vec1AtQPs[iq], vec2AtQPs[iq] ,vec3AtQPs[iq]) * + ((*b) * grdUhAtQP[iq]); + } + + + // =========== General_FOT ========== + + General_FOT::General_FOT(std::vector<DOFVectorBase<double>*> vecs, + std::vector<DOFVectorBase<double>*> grads, + TertiaryAbstractFunction<WorldVector<double>, + WorldVector<double>, + std::vector<double>, + std::vector<WorldVector<double> > > *af) + : FirstOrderTerm(af->getDegree()), vecs_(vecs), grads_(grads), f_(af) + { + vecsAtQPs_.resize(vecs_.size()); + gradsAtQPs_.resize(grads_.size()); + + for (int i = 0; i < static_cast<int>(vecs.size()); i++) { + TEST_EXIT(vecs[i])("One vector is NULL!\n"); + + auxFeSpaces.insert(vecs[i]->getFESpace()); + } + + for (int i = 0; i < static_cast<int>(grads.size()); i++) { + TEST_EXIT(grads[i])("One gradient vector is NULL!\n"); + + auxFeSpaces.insert(grads[i]->getFESpace()); + } + } + + void General_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + int nVecs = static_cast<int>(vecs_.size()); + int nGrads = static_cast<int>(grads_.size()); + + coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); + + for (int i = 0; i < nVecs; i++) + vecsAtQPs_[i] = getVectorAtQPs(vecs_[i], elInfo, subAssembler, quad); + for (int i = 0; i < nGrads; i++) + gradsAtQPs_[i] = getGradientsAtQPs(grads_[i], elInfo, subAssembler, quad); + } + + void General_FOT::getLb(const ElInfo *elInfo, + int nPoints, + VectorOfFixVecs<DimVec<double> >& result) const + { + int nVecs = static_cast<int>(vecs_.size()); + int nGrads = static_cast<int>(grads_.size()); + + std::vector<double> vecsArg(nVecs); + std::vector<WorldVector<double> > gradsArg(nGrads); + + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + + for (int iq = 0; iq < nPoints; iq++) { + for (int i = 0; i < nVecs; i++) + vecsArg[i] = vecsAtQPs_[i][iq]; + for (int i = 0; i < nGrads; i++) + gradsArg[i] = gradsAtQPs_[i][iq]; + + lb(Lambda, (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg), + result[iq], 1.0); + } + } + + void General_FOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) + { + int dow = Global::getGeo(WORLD); + int nVecs = static_cast<int>(vecs_.size()); + int nGrads = static_cast<int>(grads_.size()); + + std::vector<double> vecsArg(nVecs); + std::vector<WorldVector<double> > gradsArg(nGrads); + + if (grdUhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + double resultQP = 0.0; + + for (int i = 0; i < nVecs; i++) + vecsArg[i] = vecsAtQPs_[i][iq]; + for (int i = 0; i < nGrads; i++) + gradsArg[i] = gradsAtQPs_[i][iq]; + + const WorldVector<double> &b = (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg); + + for (int i = 0; i < dow; i++) + resultQP += grdUhAtQP[iq][i] * b[i]; + + result[iq] += factor * resultQP; + } + } + } + + + // =========== GeneralParametric_FOT ========== + + GeneralParametric_FOT::GeneralParametric_FOT(std::vector<DOFVectorBase<double>*> vecs, + std::vector<DOFVectorBase<double>*> grads, + QuartAbstractFunction<WorldVector<double>, + WorldVector<double>, + WorldVector<double>, + std::vector<double>, + std::vector<WorldVector<double> > > *af) + : FirstOrderTerm(af->getDegree()), vecs_(vecs), grads_(grads), f_(af) + { + vecsAtQPs_.resize(vecs_.size()); + gradsAtQPs_.resize(grads_.size()); + + for (int i = 0; i < static_cast<int>(vecs.size()); i++) { + TEST_EXIT(vecs[i])("One vector is NULL!\n"); + + auxFeSpaces.insert(vecs[i]->getFESpace()); + } + + for (int i = 0; i < static_cast<int>(grads.size()); i++) { + TEST_EXIT(grads[i])("One gradient vector is NULL!\n"); + + auxFeSpaces.insert(grads[i]->getFESpace()); + } + } + + + void GeneralParametric_FOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + int nVecs = static_cast<int>(vecs_.size()); + int nGrads = static_cast<int>(grads_.size()); + + elInfo->getElementNormal(elementNormal_); + coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); + + for (int i = 0; i < nVecs; i++) + vecsAtQPs_[i] = getVectorAtQPs(vecs_[i], elInfo, subAssembler, quad); + for (int i = 0; i < nGrads; i++) + gradsAtQPs_[i] = getGradientsAtQPs(grads_[i], elInfo, subAssembler, quad); + } + + void GeneralParametric_FOT::getLb(const ElInfo *elInfo, + int nPoints, + VectorOfFixVecs<DimVec<double> >& result) const + { + int nVecs = static_cast<int>(vecs_.size()); + int nGrads = static_cast<int>(grads_.size()); + + std::vector<double> vecsArg(nVecs); + std::vector<WorldVector<double> > gradsArg(nGrads); + + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) { + for (int i = 0; i < nVecs; i++) + vecsArg[i] = vecsAtQPs_[i][iq]; + for (int i = 0; i < nGrads; i++) + gradsArg[i] = gradsAtQPs_[i][iq]; + + lb(Lambda, (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg), result[iq], 1.0); + } + } + + void GeneralParametric_FOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) + { + int dow = Global::getGeo(WORLD); + int nVecs = static_cast<int>(vecs_.size()); + int nGrads = static_cast<int>(grads_.size()); + + std::vector<double> vecsArg(nVecs); + std::vector<WorldVector<double> > gradsArg(nGrads); + + if (grdUhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + double resultQP = 0.0; + + for (int i = 0; i < nVecs; i++) + vecsArg[i] = vecsAtQPs_[i][iq]; + for (int i = 0; i < nGrads; i++) + gradsArg[i] = gradsAtQPs_[i][iq]; + + const WorldVector<double> &b = (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg); + + for (int i = 0; i < dow; i++) + resultQP += grdUhAtQP[iq][i] * b[i]; + + result[iq] += factor * resultQP; + } + } + } + + + +} diff --git a/AMDiS/src/FirstOrderTerm.h b/AMDiS/src/FirstOrderTerm.h new file mode 100644 index 00000000..a86205f3 --- /dev/null +++ b/AMDiS/src/FirstOrderTerm.h @@ -0,0 +1,770 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == TU Dresden == +// == == +// == Institut f�r Wissenschaftliches Rechnen == +// == Zellescher Weg 12-14 == +// == 01069 Dresden == +// == germany == +// == == +// ============================================================================ +// == == +// == https://gforge.zih.tu-dresden.de/projects/amdis/ == +// == == +// ============================================================================ + +/** \file FirstOrderTerm.h */ + +#ifndef AMDIS_FIRST_ORDER_TERM_H +#define AMDIS_FIRST_ORDER_TERM_H + +#include "AMDiS_fwd.h" +#include "OperatorTerm.h" +#include "AbstractFunction.h" +#include "ElInfo.h" + +namespace AMDiS { + + /** + * \ingroup Assembler + * + * \brief + * Describes the first order terms: \f$ b \cdot \nabla u(\vec{x}) \f$ + */ + class FirstOrderTerm : public OperatorTerm + { + public: + /// Constructor. + FirstOrderTerm(int deg) + : OperatorTerm(deg) + {} + + /// Destructor. + virtual ~FirstOrderTerm() {} + + /// Evaluation of \f$ \Lambda b \f$. + virtual void getLb(const ElInfo *elInfo, + int nPoints, + VectorOfFixVecs<DimVec<double> >& result) const = 0; + + /// Implenetation of FirstOrderTerm::eval(). + void eval(int nPoints, + const double *, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *, + double *result, + double factor) + { + int dow = Global::getGeo(WORLD); + + if (grdUhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + double resultQP = 0.0; + for (int i = 0; i < dow; i++) + resultQP += grdUhAtQP[iq][i]; + + result[iq] += resultQP * factor; + } + } + } + + }; + + /** + * \ingroup Assembler + * + * \brief + * First order term: \f$ b \cdot \nabla u(\vec{x}) \f$ with a vector b which + * only consits of entries equal to one. + */ + class Simple_FOT : public FirstOrderTerm + { + public: + /// Constructor. + Simple_FOT() + : FirstOrderTerm(0) + {} + + /// Implements FirstOrderTerm::getLb(). + inline void getLb(const ElInfo *elInfo, + int nPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + + for (int iq = 0; iq < nPoints; iq++) + l1(Lambda, Lb[iq], 1.0); + } + }; + + /** + * \ingroup Assembler + * + * \brief + * First order term: \f$ b \cdot \nabla u(\vec{x}) \f$ with a vector b which + * only consits of entries equal to one. + */ + class FactorSimple_FOT : public FirstOrderTerm + { + public: + /// Constructor. + FactorSimple_FOT(double f) + : FirstOrderTerm(0) + { + factor = new double; + *factor = f; + } + + /// Constructor. + FactorSimple_FOT(double *fptr) + : FirstOrderTerm(0), factor(fptr) + {} + + /// Implements FirstOrderTerm::getLb(). + inline void getLb(const ElInfo *elInfo, int nPoints, VectorOfFixVecs<DimVec<double> >& Lb) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + + for (int iq = 0; iq < nPoints; iq++) + l1(Lambda, Lb[iq], (*factor)); + } + + private: + /// Pointer to the factor. + double *factor; + }; + + /** + * \ingroup Assembler + * + * \brief + * First order term: \f$ b \cdot \nabla u(\vec{x}) \f$ with a given vector b. + */ + class Vector_FOT : public FirstOrderTerm + { + public: + /// Constructor. + Vector_FOT(WorldVector<double> wv) + : FirstOrderTerm(0), b(wv) + {} + + /// Constructor. + Vector_FOT(int bIdx) + : FirstOrderTerm(0) + { + bOne = bIdx; + } + + /// Implements FirstOrderTerm::getLb(). + inline void getLb(const ElInfo *elInfo, + int nPoints, + VectorOfFixVecs<DimVec<double> >&Lb) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + + if (bOne > -1) { + for (int iq = 0; iq < nPoints; iq++) + lb_one(Lambda, Lb[iq], 1.0); + } else { + for (int iq = 0; iq < nPoints; iq++) + lb(Lambda, b, Lb[iq], 1.0); + } + } + + /// Implements FirstOrderTerm::eval(). + void eval(int nPoints, + const double *, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *, + double *result, + double factor) + { + if (grdUhAtQP) + for (int iq = 0; iq < nPoints; iq++) + result[iq] += b * grdUhAtQP[iq] * factor; + } + + protected: + /// Vector which is multiplied with \f$ \nabla u(\vec{x}) \f$ + WorldVector<double> b; + }; + + /** + * \ingroup Assembler + * + * \brief + * Simple_FOT multiplied with \f$ f(v(\vec{x})) \f$. + */ + class VecAtQP_FOT : public FirstOrderTerm + { + public: + /// Constructor. + VecAtQP_FOT(DOFVectorBase<double> *dv, + AbstractFunction<double, double> *af, + WorldVector<double> *wv); + + /// Constructor. + VecAtQP_FOT(DOFVectorBase<double> *dv, + AbstractFunction<double, double> *af, + int bIdx); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements FirstOrderTerm::getLb(). + void getLb(const ElInfo *elInfo, int nPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const; + + /// Implements FirstOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + protected: + /// DOFVector to be evaluated at quadrature points. + DOFVectorBase<double>* vec; + + /// v at quadrature points. + double *vecAtQPs; + + /// Function f. + AbstractFunction<double, double> *f; + + /// + WorldVector<double> *b; + }; + + /** + * \ingroup Assembler + * + * \brief + * Simple_FOT multiplied with \f$ f(\vec{x}) \f$. + */ + class CoordsAtQP_FOT : public FirstOrderTerm + { + public: + /// Constructor. + CoordsAtQP_FOT(AbstractFunction<double, WorldVector<double> > *af) + : FirstOrderTerm(af->getDegree()), g(af) + {} + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements FistOrderTerm::getLb(). + void getLb(const ElInfo *elInfo, int nPoints,VectorOfFixVecs<DimVec<double> >&Lb) const; + + /// Implements FirstOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + protected: + /// Stores coordinates at quadrature points. Set in \ref initElement(). + WorldVector<double>* coordsAtQPs; + + /// Function avaluated at world coordinates. + AbstractFunction<double, WorldVector<double> > *g; + }; + + /** + * \ingroup Assembler + * + * \brief + * Vector_FOT multiplied with \f$ f(\vec{x}) \f$. + */ + class VecCoordsAtQP_FOT : public FirstOrderTerm + { + public: + /// Constructor. + VecCoordsAtQP_FOT(AbstractFunction<double, WorldVector<double> > *af, + WorldVector<double> wv) + : FirstOrderTerm(af->getDegree()), g(af), b(wv) + {} + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements FistOrderTerm::getLb(). + void getLb(const ElInfo *elInfo, int nPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const; + + /// Implements FirstOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + protected: + /// Stores coordinates at quadrature points. Set in \ref initElement(). + WorldVector<double>* coordsAtQPs; + + /// Function evaluated at world coordinates. + AbstractFunction<double, WorldVector<double> > *g; + + /// Coefficient vector. + WorldVector<double> b; + }; + + /** + * \ingroup Assembler + * + * \brief + * First order term: \f$ b(\nabla v(\vec{x})) \cdot \nabla u(\vec{x})\f$. + */ + class VectorGradient_FOT : public FirstOrderTerm + { + public: + /// Constructor. + VectorGradient_FOT(DOFVectorBase<double> *dv, + AbstractFunction<WorldVector<double>, WorldVector<double> > *af); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements FirstOrderTerm::getLb(). + void getLb(const ElInfo *elInfo, int nPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const; + + /// Implements FirstOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + protected: + DOFVectorBase<double>* vec; + + /// Function for b. + AbstractFunction<WorldVector<double>, WorldVector<double> > *f; + + /// Gradient of v at quadrature points. + WorldVector<double> *gradAtQPs; + }; + + /** + * \ingroup Assembler + * + * \brief + * First order term: \f$ b(v(\vec{x})) \cdot \nabla u(\vec{x})\f$. + */ + class VectorFct_FOT : public FirstOrderTerm + { + public: + /// Constructor. + VectorFct_FOT(DOFVectorBase<double> *dv, + AbstractFunction<WorldVector<double>, double> *fct); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements FirstOrderTerm::getLb(). + void getLb(const ElInfo *elInfo, int qPoint, + VectorOfFixVecs<DimVec<double> >& Lb) const; + + /// Implements FirstOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + protected: + /// DOFVector to be evaluated at quadrature points. + DOFVectorBase<double>* vec; + + /// Vector v at quadrature points. + double *vecAtQPs; + + /// Function for b. + AbstractFunction<WorldVector<double>, double> *vecFct; + }; + + /** + * \ingroup Assembler + * + * \brief + * + */ + class VecFctAtQP_FOT : public FirstOrderTerm + { + public: + /// Constructor. + VecFctAtQP_FOT(AbstractFunction<WorldVector<double>, WorldVector<double> > *af) + : FirstOrderTerm(af->getDegree()), g(af) + {} + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements FistOrderTerm::getLb(). + void getLb(const ElInfo *elInfo, int nPoints, + VectorOfFixVecs<DimVec<double> >&Lb) const; + + /// Implements FirstOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + protected: + /// Stores coordinates at quadrature points. Set in \ref initElement(). + WorldVector<double>* coordsAtQPs; + + /// Function avaluated at world coordinates. + AbstractFunction<WorldVector<double>, WorldVector<double> > *g; + }; + + + /** + * \ingroup Assembler + * + * \brief + * First order term: \f$ b(v(\vec{x}), \nabla w(\vec{x})) \cdot \nabla u(\vec{x})\f$. + */ + class VecGrad_FOT : public FirstOrderTerm + { + public: + /// Constructor. + VecGrad_FOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, + BinaryAbstractFunction<WorldVector<double>, double, WorldVector<double> > *fct); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implementation of \ref OperatorTerm::initElement() for multilpe meshes. + void initElement(const ElInfo* smallElInfo, + const ElInfo* largeElInfo, + SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements FirstOrderTerm::getLb(). + void getLb(const ElInfo *elInfo, int qPoint, + VectorOfFixVecs<DimVec<double> >& Lb) const; + + /// Implements FirstOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + protected: + /// DOFVector to be evaluated at quadrature points. + DOFVectorBase<double>* vec1; + DOFVectorBase<double>* vec2; + + /// Vector v at quadrature points. + double *vecAtQPs; + + WorldVector<double> *gradAtQPs; + + /// Function for b. + BinaryAbstractFunction<WorldVector<double>, double, WorldVector<double> > *vecFct; + }; + + + /** + * \ingroup Assembler + * + * \brief + * First order term: \f$ b(\nabla v(\vec{x}), \nabla w(\vec{x})) \cdot \nabla u(\vec{x})\f$. + */ + class FctGrad2_FOT : public FirstOrderTerm + { + public: + /// Constructor + FctGrad2_FOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, + BinaryAbstractFunction<WorldVector<double>, WorldVector<double>, WorldVector<double> > *vecFct_) + : FirstOrderTerm(vecFct_->getDegree()), vec1(dv1), vec2(dv2), vecFct(vecFct_) + {} + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements FirstOrderTerm::getLb(). + void getLb(const ElInfo *elInfo, int qPoint, + VectorOfFixVecs<DimVec<double> >& Lb) const; + + /// Implements FirstOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + protected: + /// DOFVector to be evaluated at quadrature points. + DOFVectorBase<double>* vec1; + + /// DOFVector to be evaluated at quadrature points. + DOFVectorBase<double>* vec2; + + /// Gradient v at quadrature points. + WorldVector<double> *grad1AtQPs; + + /// Gradient v at quadrature points. + WorldVector<double> *grad2AtQPs; + + /// Function for b. + BinaryAbstractFunction<WorldVector<double>, WorldVector<double>, WorldVector<double> > *vecFct; + }; + + + class Vec2AndGradAtQP_FOT : public FirstOrderTerm + { + public: + Vec2AndGradAtQP_FOT(DOFVectorBase<double> *dv1, + DOFVectorBase<double> *dv2, + TertiaryAbstractFunction<double, double, double, WorldVector<double> > *f_, WorldVector<double> *b_); + + void initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad = NULL); + + void getLb(const ElInfo *elInfo, + int nPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const; + + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + protected: + DOFVectorBase<double>* vec1; + DOFVectorBase<double>* vec2; + + double *vec1AtQPs; + double *vec2AtQPs; + WorldVector<double> *gradAtQPs1; + + TertiaryAbstractFunction<double, double, double, WorldVector<double> > *f; + WorldVector<double> *b; + }; + + + class FctVecAtQP_FOT : public FirstOrderTerm + { + public: + FctVecAtQP_FOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<double, WorldVector<double>, double> *f_, + WorldVector<double> *b_); + + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + void getLb(const ElInfo *elInfo, int nPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const; + + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + protected: + DOFVectorBase<double>* vec; + double *vecAtQPs; + WorldVector<double> *coordsAtQPs; + BinaryAbstractFunction<double, WorldVector<double>, double> *f; + WorldVector<double> *b; + }; + + + class Vec2AtQP_FOT : public FirstOrderTerm + { + public: + Vec2AtQP_FOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, + BinaryAbstractFunction<double, double, double> *af, + WorldVector<double> *b_); + + Vec2AtQP_FOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, + BinaryAbstractFunction<double, double, double> *af, + int bIdx); + + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + void getLb(const ElInfo *elInfo, int nPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const; + + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + protected: + DOFVectorBase<double>* vec1; + DOFVectorBase<double>* vec2; + double *vec1AtQPs; + double *vec2AtQPs; + /// Function f. + BinaryAbstractFunction<double, double, double> *f; + WorldVector<double> *b; + }; + + + class Vec3FctAtQP_FOT : public FirstOrderTerm + { + public: + Vec3FctAtQP_FOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, DOFVectorBase<double> *dv3, + TertiaryAbstractFunction<double, double, double, double> *f, + WorldVector<double> *b); + + Vec3FctAtQP_FOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, DOFVectorBase<double> *dv3, + TertiaryAbstractFunction<double, double, double, double> *f, + int b); + + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + void getLb(const ElInfo *elInfo, int nPoints, + VectorOfFixVecs<DimVec<double> >& Lb) const; + + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + protected: + DOFVectorBase<double>* vec1; + DOFVectorBase<double>* vec2; + DOFVectorBase<double>* vec3; + TertiaryAbstractFunction<double, double, double, double>* f; + double *vec1AtQPs; + double *vec2AtQPs; + double *vec3AtQPs; + WorldVector<double> *b; + }; + + + class General_FOT : public FirstOrderTerm + { + public: + /// Constructor + General_FOT(std::vector<DOFVectorBase<double>*> vecs, + std::vector<DOFVectorBase<double>*> grads, + TertiaryAbstractFunction<WorldVector<double>, + WorldVector<double>, + std::vector<double>, + std::vector<WorldVector<double> > > *f); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo*, + SubAssembler* , + Quadrature *quad= NULL); + + /// Implements FirstOrderTerm::getLb(). + void getLb(const ElInfo *elInfo, int nPoints, + VectorOfFixVecs<DimVec<double> >& result) const; + + /// Implenetation of FirstOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + protected: + std::vector<DOFVectorBase<double>*> vecs_; + + std::vector<DOFVectorBase<double>*> grads_; + + TertiaryAbstractFunction<WorldVector<double>, + WorldVector<double>, + std::vector<double>, + std::vector<WorldVector<double> > > *f_; + + WorldVector<double> *coordsAtQPs_; + + std::vector<double*> vecsAtQPs_; + + std::vector<WorldVector<double>*> gradsAtQPs_; + }; + + + class GeneralParametric_FOT : public FirstOrderTerm + { + public: + /// Constructor + GeneralParametric_FOT(std::vector<DOFVectorBase<double>*> vecs, + std::vector<DOFVectorBase<double>*> grads, + QuartAbstractFunction<WorldVector<double>, + WorldVector<double>, + WorldVector<double>, + std::vector<double>, + std::vector<WorldVector<double> > > *f); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo*, SubAssembler*, Quadrature *quad = NULL); + + /// Implements FirstOrderTerm::getLb(). + void getLb(const ElInfo *elInfo, int nPoints, + VectorOfFixVecs<DimVec<double> >& result) const; + + /// Implenetation of FirstOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + protected: + std::vector<DOFVectorBase<double>*> vecs_; + + std::vector<DOFVectorBase<double>*> grads_; + + QuartAbstractFunction<WorldVector<double>, + WorldVector<double>, + WorldVector<double>, + std::vector<double>, + std::vector<WorldVector<double> > > *f_; + + WorldVector<double> *coordsAtQPs_; + WorldVector<double> elementNormal_; + + std::vector<double*> vecsAtQPs_; + + std::vector<WorldVector<double>*> gradsAtQPs_; + }; + +} + +#endif diff --git a/AMDiS/src/Operator.cc b/AMDiS/src/Operator.cc index b125ef2e..1c8658d6 100644 --- a/AMDiS/src/Operator.cc +++ b/AMDiS/src/Operator.cc @@ -8,9 +8,6 @@ namespace AMDiS { - const Flag OperatorTerm::PW_CONST = 1; - const Flag OperatorTerm::SYMMETRIC = 2; - const Flag Operator::MATRIX_OPERATOR = 1; const Flag Operator::VECTOR_OPERATOR = 2; @@ -51,171 +48,6 @@ namespace AMDiS { } - void OperatorTerm::setSymmetric(bool symm) - { - if (symm) - properties.setFlag(SYMMETRIC); - else - properties.unsetFlag(SYMMETRIC); - } - - bool OperatorTerm::isSymmetric() - { - return properties.isSet(SYMMETRIC); - } - - double *OperatorTerm::getVectorAtQPs(DOFVectorBase<double>* vec, - const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - FUNCNAME("OperatorTerm::getVectorAtQPs()"); - - TEST_EXIT_DBG(elInfo->getMesh() == vec->getFESpace()->getMesh()) - ("There is something wrong!\n"); - - return subAssembler->getVectorAtQPs(vec, elInfo, quad); - } - - double *OperatorTerm::getVectorAtQPs(DOFVectorBase<double>* vec, - const ElInfo* smallElInfo, - const ElInfo* largeElInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - FUNCNAME("OperatorTerm::getVectorAtQPs()"); - - TEST_EXIT(smallElInfo->getMesh() == vec->getFESpace()->getMesh() || - largeElInfo->getMesh() == vec->getFESpace()->getMesh()) - ("There is something wrong!\n"); - - if (smallElInfo->getLevel() == largeElInfo->getLevel()) { - - // Both elements have the same size, so we can use the simple procedure - // to determine the vecAtQPs. - - if (vec->getFESpace()->getMesh() == smallElInfo->getMesh()) - return subAssembler->getVectorAtQPs(vec, smallElInfo, quad); - else - return subAssembler->getVectorAtQPs(vec, largeElInfo, quad); - - } else { - - // The two elements are different. If the vector is defined on the mesh of the - // small element, we can still use the simple procedure to determine the vecAtQPs. - - if (vec->getFESpace()->getMesh() == largeElInfo->getMesh()) - return subAssembler->getVectorAtQPs(vec, smallElInfo, largeElInfo, quad); - else - return subAssembler->getVectorAtQPs(vec, smallElInfo, quad); - } - } - - WorldVector<double>* OperatorTerm::getGradientsAtQPs(DOFVectorBase<double>* vec, - const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - FUNCNAME("OperatorTerm::getGradientsAtQPs()"); - - TEST_EXIT_DBG(elInfo->getMesh() == vec->getFESpace()->getMesh()) - ("There is something wrong!\n"); - - return subAssembler->getGradientsAtQPs(vec, elInfo, quad); - } - - WorldVector<double>* OperatorTerm::getGradientsAtQPs(DOFVectorBase<double>* vec, - const ElInfo* smallElInfo, - const ElInfo* largeElInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - FUNCNAME("OperatorTerm::getGradientsAtQPs()"); - - ERROR_EXIT("Not yet tested!\n"); - - TEST_EXIT(smallElInfo->getMesh() == vec->getFESpace()->getMesh() || - largeElInfo->getMesh() == vec->getFESpace()->getMesh()) - ("There is something wrong!\n"); - - if (smallElInfo->getLevel() == largeElInfo->getLevel()) { - - // Both elements have the same size, so we can use the simple procedure - // to determine the gradients. - - if (vec->getFESpace()->getMesh() == smallElInfo->getMesh()) - return subAssembler->getGradientsAtQPs(vec, smallElInfo, quad); - else - return subAssembler->getGradientsAtQPs(vec, largeElInfo, quad); - - } else { - - // The two elements are different. If the vector is defined on the mesh of the - // small element, we can still use the simple procedure to determine the gradients. - - if (vec->getFESpace()->getMesh() == largeElInfo->getMesh()) - return subAssembler->getGradientsAtQPs(vec, smallElInfo, largeElInfo, quad); - else - return subAssembler->getGradientsAtQPs(vec, smallElInfo, quad); - } - } - - void OperatorTerm::lalt(const DimVec<WorldVector<double> >& Lambda, - const WorldMatrix<double>& matrix, - DimMat<double>& LALt, - bool symm, - double factor) const - { - int j, k, l; - const int dimOfWorld = Global::getGeo(WORLD); - int dim = LALt.getNumRows() - 1; - - double val = 0.0; - - if (symm) { - for (int i = 0; i <= dim; i++) { - val = 0.0; - for (k = 0; k < dimOfWorld; k++) - for (l = 0; l < dimOfWorld; l++) - val += Lambda[i][k] * matrix[k][l] * Lambda[i][l]; - val *= factor; - LALt[i][i] += val; - for (j = i + 1; j <= dim; j++) { - val = 0.0; - for (k = 0; k < dimOfWorld; k++) - for (l = 0; l < dimOfWorld; l++) - val += Lambda[i][k] * matrix[k][l] * Lambda[j][l]; - val *= factor; - LALt[i][j] += val; - LALt[j][i] += val; - } - } - } else { - for (int i = 0; i <= dim; i++) { - for (j = 0; j <= dim; j++) { - val = 0.0; - for (k = 0; k < dimOfWorld; k++) - for (l = 0; l < dimOfWorld; l++) - val += Lambda[i][k] * matrix[k][l] * Lambda[j][l]; - val *= factor; - LALt[i][j] += val; - } - } - } - } - - void OperatorTerm::lalt_kl(const DimVec<WorldVector<double> >& Lambda, - int k, int l, - DimMat<double>& LALt, - double factor) - { - int dim = LALt.getNumRows() - 1; - - for (int i = 0; i <= dim; i++) - for (int j = 0; j <= dim; j++) - LALt[i][j] += factor * Lambda[i][k] * Lambda[j][l]; - } - Operator::Operator(Flag operatorType, const FiniteElemSpace *row, const FiniteElemSpace *col) @@ -339,2922 +171,17 @@ namespace AMDiS { } - - VecAtQP_ZOT::VecAtQP_ZOT(DOFVectorBase<double> *dv, - AbstractFunction<double, double> *af) - : ZeroOrderTerm(af ? af->getDegree() : 0), vec(dv), f(af) - { - TEST_EXIT(dv)("No vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - } - - MultVecAtQP_ZOT::MultVecAtQP_ZOT(DOFVectorBase<double> *dv1, - DOFVectorBase<double> *dv2, - AbstractFunction<double, double> *af1, - AbstractFunction<double, double> *af2) - : ZeroOrderTerm(af1->getDegree() + af2->getDegree()), - vec1(dv1), vec2(dv2), f1(af1), f2(af2) - { - TEST_EXIT(dv1)("No first vector!\n"); - TEST_EXIT(dv2)("No second vector!\n"); - - auxFeSpaces.insert(dv1->getFESpace()); - auxFeSpaces.insert(dv2->getFESpace()); - } - - Vec2AtQP_ZOT::Vec2AtQP_ZOT(DOFVectorBase<double> *dv1, - DOFVectorBase<double> *dv2, - BinaryAbstractFunction<double, double, double> *af) - : ZeroOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), f(af) - { - TEST_EXIT(dv1)("No first vector!\n"); - TEST_EXIT(dv2)("No second vector!\n"); - - auxFeSpaces.insert(dv1->getFESpace()); - auxFeSpaces.insert(dv2->getFESpace()); - } - - Vec3AtQP_ZOT::Vec3AtQP_ZOT(DOFVectorBase<double> *dv1, - DOFVectorBase<double> *dv2, - DOFVectorBase<double> *dv3, - TertiaryAbstractFunction<double, double, double, double> *af) - : ZeroOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), vec3(dv3), f(af) - { - TEST_EXIT(dv1)("No first vector!\n"); - TEST_EXIT(dv2)("No second vector!\n"); - TEST_EXIT(dv3)("No thierd vector!\n"); - - auxFeSpaces.insert(dv1->getFESpace()); - auxFeSpaces.insert(dv2->getFESpace()); - auxFeSpaces.insert(dv3->getFESpace()); - } - - FctGradientCoords_ZOT::FctGradientCoords_ZOT(DOFVectorBase<double> *dv, - BinaryAbstractFunction<double, WorldVector<double>, WorldVector<double> > *af) - : ZeroOrderTerm(af->getDegree()), vec(dv), f(af) - { - TEST_EXIT(dv)("No vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - } - - VecGradCoordsAtQP_ZOT::VecGradCoordsAtQP_ZOT(DOFVectorBase<double> *dv, - TertiaryAbstractFunction<double, double, WorldVector<double>, WorldVector<double> > *af) - : ZeroOrderTerm(af->getDegree()), vec(dv), f(af) - { - TEST_EXIT(dv)("No vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - } - - VecAndCoordsAtQP_ZOT::VecAndCoordsAtQP_ZOT(DOFVectorBase<double> *dv, - BinaryAbstractFunction<double, double, WorldVector<double> > *af) - : ZeroOrderTerm(af->getDegree()), vec(dv), f(af) - { - TEST_EXIT(dv)("No vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - } - - Vec2AndGradAtQP_ZOT::Vec2AndGradAtQP_ZOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, - TertiaryAbstractFunction<double, double, WorldVector<double>, double > *af) - : ZeroOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), f(af) - { - TEST_EXIT(dv1)("No first vector!\n"); - TEST_EXIT(dv2)("No second vector!\n"); - - auxFeSpaces.insert(dv1->getFESpace()); - auxFeSpaces.insert(dv2->getFESpace()); - } - - FctGradient_ZOT::FctGradient_ZOT(DOFVectorBase<double> *dv, - AbstractFunction<double, WorldVector<double> > *af) - : ZeroOrderTerm(af->getDegree()), vec(dv), f(af) - { - TEST_EXIT(dv)("No vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - } - - VecAndGradAtQP_ZOT::VecAndGradAtQP_ZOT(DOFVectorBase<double> *dv, - BinaryAbstractFunction<double, double, WorldVector<double> > *af) - : ZeroOrderTerm(af->getDegree()), vec(dv), f(af) - { - TEST_EXIT(dv)("No vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - } - - VecAndGradVecAtQP_ZOT::VecAndGradVecAtQP_ZOT(DOFVectorBase<double> *dv, - DOFVectorBase<double> *dGrd, - BinaryAbstractFunction<double, double, WorldVector<double> > *af) - : ZeroOrderTerm(af->getDegree()), vec(dv), vecGrd(dGrd), f(af) - { - TEST_EXIT(dv)("No vector!\n"); - TEST_EXIT(dGrd)("No gradient vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - auxFeSpaces.insert(dGrd->getFESpace()); - } - - VecAndGradVec2AtQP_ZOT::VecAndGradVec2AtQP_ZOT(DOFVectorBase<double> *dv, - DOFVectorBase<double> *dGrd1, - DOFVectorBase<double> *dGrd2, - TertiaryAbstractFunction<double, double, WorldVector<double>, WorldVector<double> > *af) - : ZeroOrderTerm(af->getDegree()), vec(dv), vecGrd1(dGrd1), vecGrd2(dGrd2), f(af) - { - TEST_EXIT(dv)("No vector!\n"); - TEST_EXIT(dGrd1)("No first gradient vector!\n"); - TEST_EXIT(dGrd2)("No second gradient vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - auxFeSpaces.insert(dGrd1->getFESpace()); - auxFeSpaces.insert(dGrd2->getFESpace()); - } - - VecOfDOFVecsAtQP_ZOT::VecOfDOFVecsAtQP_ZOT(const std::vector<DOFVectorBase<double>*>& dv, - AbstractFunction<double, std::vector<double> > *af) - : ZeroOrderTerm(af->getDegree()), vecs(dv), f(af) - { - vecsAtQPs.resize(vecs.size()); - - for (int i = 0; i < static_cast<int>(dv.size()); i++) { - TEST_EXIT(dv[i])("One vector is NULL!\n"); - - auxFeSpaces.insert(dv[i]->getFESpace()); - } - } - - VecOfGradientsAtQP_ZOT::VecOfGradientsAtQP_ZOT(const std::vector<DOFVectorBase<double>*>& dv, - AbstractFunction<double, std::vector<WorldVector<double>*> > *af) - : ZeroOrderTerm(af->getDegree()), vecs(dv), f(af) - { - gradsAtQPs.resize(vecs.size()); - - for (int i = 0; i < static_cast<int>(dv.size()); i++) { - TEST_EXIT(dv[i])("One vector is NULL!\n"); - - auxFeSpaces.insert(dv[i]->getFESpace()); - } - } - - VecDivergence_ZOT::VecDivergence_ZOT(int nComponents, - DOFVectorBase<double> *vec0, - DOFVectorBase<double> *vec1, - DOFVectorBase<double> *vec2) - : ZeroOrderTerm(0) - { - vecs.resize(nComponents); - gradsAtQPs.resize(nComponents); - vecs[0] = vec0; - vecs[1] = vec1; - vecs[2] = vec2; - - auxFeSpaces.insert(vec0->getFESpace()); - if (vec1) - auxFeSpaces.insert(vec1->getFESpace()); - if (vec2) - auxFeSpaces.insert(vec2->getFESpace()); - } - - - VecAndVecOfGradientsAtQP_ZOT::VecAndVecOfGradientsAtQP_ZOT(DOFVector<double> *v, - const std::vector<DOFVector<double>*>& dv, - BinaryAbstractFunction<double, double, std::vector<WorldVector<double>*> > *af) - : ZeroOrderTerm(af->getDegree()), vec(v), vecs(dv), f(af) - { - gradsAtQPs.resize(vecs.size()); - - TEST_EXIT(v)("No vector!\n"); - - auxFeSpaces.insert(v->getFESpace()); - for (int i = 0; i < static_cast<int>(dv.size()); i++) { - TEST_EXIT(dv[i])("One gradient vector is NULL!\n"); - - auxFeSpaces.insert(dv[i]->getFESpace()); - } - } - - - Vec2AndGrad2AtQP_ZOT::Vec2AndGrad2AtQP_ZOT(DOFVectorBase<double> *dv1, - DOFVectorBase<double> *dv2, - QuartAbstractFunction<double, double, double, WorldVector<double>,WorldVector<double> > *af) - : ZeroOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), f(af) - { - TEST_EXIT(dv1)("No first vector!\n"); - TEST_EXIT(dv2)("No second vector!\n"); - - auxFeSpaces.insert(dv1->getFESpace()); - auxFeSpaces.insert(dv2->getFESpace()); - } - - void Vec2AndGrad2AtQP_ZOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs1 = getVectorAtQPs(vec1, elInfo, subAssembler, quad); - vecAtQPs2 = getVectorAtQPs(vec2, elInfo, subAssembler, quad); - gradAtQPs1 = getGradientsAtQPs(vec1, elInfo, subAssembler, quad); - gradAtQPs2 = getGradientsAtQPs(vec2, elInfo, subAssembler, quad); - } - - - void Vec2AndGrad2AtQP_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - for (int iq = 0; iq < nPoints; iq++) - result[iq] += - fac * (*f)(vecAtQPs1[iq], vecAtQPs2[iq], gradAtQPs1[iq], gradAtQPs2[iq]) * - uhAtQP[iq]; - } - - void Vec2AndGrad2AtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) - { - for (int iq = 0; iq < nPoints; iq++) - C[iq] += (*f)(vecAtQPs1[iq], vecAtQPs2[iq], gradAtQPs1[iq], gradAtQPs2[iq]); - } - - Vec2AndGradVecAtQP_ZOT::Vec2AndGradVecAtQP_ZOT(DOFVectorBase<double> *dv1, - DOFVectorBase<double> *dv2, - DOFVectorBase<double> *dGrd, - TertiaryAbstractFunction<double, double,double, WorldVector<double> > *af) - : ZeroOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), vecGrd(dGrd), f(af) - { - TEST_EXIT(dv1)("No vector!\n"); - TEST_EXIT(dv2)("No vector!\n"); - TEST_EXIT(dGrd)("No gradient vector!\n"); - - auxFeSpaces.insert(dv1->getFESpace()); - auxFeSpaces.insert(dv2->getFESpace()); - auxFeSpaces.insert(dGrd->getFESpace()); - } - - void Vec2AndGradVecAtQP_ZOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vec1AtQPs = getVectorAtQPs(vec1, elInfo, subAssembler, quad); - vec2AtQPs = getVectorAtQPs(vec2, elInfo, subAssembler, quad); - gradAtQPs = getGradientsAtQPs(vecGrd, elInfo, subAssembler, quad); - } - - void Vec2AndGradVecAtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) - { - for (int iq = 0; iq < nPoints; iq++) - C[iq] += (*f)(vec1AtQPs[iq], vec2AtQPs[iq], gradAtQPs[iq]); - } - - void Vec2AndGradVecAtQP_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - for (int iq = 0; iq < nPoints; iq++) - result[iq] += - fac * (*f)(vec1AtQPs[iq], vec2AtQPs[iq], gradAtQPs[iq]) * uhAtQP[iq]; - } - - General_ZOT::General_ZOT(std::vector<DOFVectorBase<double>*> vecs, - std::vector<DOFVectorBase<double>*> grads, - TertiaryAbstractFunction<double, WorldVector<double>, std::vector<double>, std::vector<WorldVector<double> > > *af) - : ZeroOrderTerm(af->getDegree()), vecs_(vecs), grads_(grads), f_(af) - { - vecsAtQPs_.resize(vecs_.size()); - gradsAtQPs_.resize(grads_.size()); - - for (int i = 0; i < static_cast<int>(vecs.size()); i++) { - TEST_EXIT(vecs[i])("One vector is NULL!\n"); - - auxFeSpaces.insert(vecs[i]->getFESpace()); - } - - for (int i = 0; i < static_cast<int>(grads.size()); i++) { - TEST_EXIT(grads[i])("One gradient vector is NULL!\n"); - - auxFeSpaces.insert(grads[i]->getFESpace()); - } - - vecsArg.resize(vecs_.size()); - gradsArg.resize(grads_.size()); - } - - GeneralParametric_ZOT::GeneralParametric_ZOT(std::vector<DOFVectorBase<double>*> vecs, - std::vector<DOFVectorBase<double>*> grads, - QuartAbstractFunction<double, - WorldVector<double>, - WorldVector<double>, - std::vector<double>, - std::vector<WorldVector<double> > > *af) - : ZeroOrderTerm(af->getDegree()), vecs_(vecs), grads_(grads), f_(af) - { - vecsAtQPs_.resize(vecs_.size()); - gradsAtQPs_.resize(grads_.size()); - - for (int i = 0; i < static_cast<int>(vecs.size()); i++) { - TEST_EXIT(vecs[i])("One vector is NULL!\n"); - - auxFeSpaces.insert(vecs[i]->getFESpace()); - } - - for (int i = 0; i < static_cast<int>(grads.size()); i++) { - TEST_EXIT(grads[i])("One gradient vector is NULL!\n"); - - auxFeSpaces.insert(grads[i]->getFESpace()); - } - } - - VecAtQP_FOT::VecAtQP_FOT(DOFVectorBase<double> *dv, - AbstractFunction<double, double> *af, - WorldVector<double> *wv) - : FirstOrderTerm(af->getDegree()), vec(dv), f(af), b(wv) - { - TEST_EXIT(dv)("No vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - } - - VecAtQP_FOT::VecAtQP_FOT(DOFVectorBase<double> *dv, - AbstractFunction<double, double> *af, - int bIdx) - : FirstOrderTerm(af->getDegree()), vec(dv), f(af) - { - TEST_EXIT(dv)("No vector!\n"); - - bOne = bIdx; - auxFeSpaces.insert(dv->getFESpace()); - } - - VectorGradient_FOT::VectorGradient_FOT(DOFVectorBase<double> *dv, - AbstractFunction<WorldVector<double>, WorldVector<double> > *af) - : FirstOrderTerm(af->getDegree()), vec(dv), f(af) - { - TEST_EXIT(dv)("No vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - } - - VectorFct_FOT::VectorFct_FOT(DOFVectorBase<double> *dv, - AbstractFunction<WorldVector<double>, double> *fct) - : FirstOrderTerm(fct->getDegree()), vec(dv), vecFct(fct) - { - TEST_EXIT(dv)("No vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - } - - VecGrad_FOT::VecGrad_FOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, - BinaryAbstractFunction<WorldVector<double>, double, WorldVector<double> > *fct) - : FirstOrderTerm(fct->getDegree()), vec1(dv1), vec2(dv2), vecFct(fct) - { - TEST_EXIT(dv1)("No first vector!\n"); - TEST_EXIT(dv2)("No second vector!\n"); - - auxFeSpaces.insert(dv1->getFESpace()); - auxFeSpaces.insert(dv2->getFESpace()); - } - - Vec2AndGradAtQP_FOT::Vec2AndGradAtQP_FOT(DOFVectorBase<double> *dv1, - DOFVectorBase<double> *dv2, - TertiaryAbstractFunction<double, double, double, WorldVector<double> > *f_, WorldVector<double> *b_) - : FirstOrderTerm(f_->getDegree()), - vec1(dv1), - vec2(dv2), - f(f_), - b(b_) - { - auxFeSpaces.insert(dv1->getFESpace()); - auxFeSpaces.insert(dv2->getFESpace()); - } - - void Vec2AndGradAtQP_FOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vec1AtQPs = subAssembler->getVectorAtQPs(vec1, elInfo, quad); - vec2AtQPs = subAssembler->getVectorAtQPs(vec2, elInfo, quad); - gradAtQPs1 = getGradientsAtQPs(vec1, elInfo, subAssembler, quad); - } - - - void Vec2AndGradAtQP_FOT::getLb(const ElInfo *elInfo, int nPoints, VectorOfFixVecs<DimVec<double> >& Lb) const { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) { - if (b) - lb(Lambda, *b, Lb[iq], (*f)(vec1AtQPs[iq], vec2AtQPs[iq],gradAtQPs1[iq])); - else - l1(Lambda, Lb[iq], (*f)(vec1AtQPs[iq], vec2AtQPs[iq], gradAtQPs1[iq])); - } - } - - void Vec2AndGradAtQP_FOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - if (grdUhAtQP) - for (int iq = 0; iq < nPoints; iq++) - result[iq] += fac * - (*f)(vec1AtQPs[iq], vec2AtQPs[iq], gradAtQPs1[iq]) * - ((*b) * grdUhAtQP[iq]); - } - - - FctVecAtQP_FOT::FctVecAtQP_FOT(DOFVectorBase<double> *dv, - BinaryAbstractFunction<double, WorldVector<double>, double> *f_, - WorldVector<double> *b_) - : FirstOrderTerm(f_->getDegree()), vec(dv), f(f_), b(b_) - { - auxFeSpaces.insert(dv->getFESpace()); - } - - - void FctVecAtQP_FOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); - coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); - } - - - void FctVecAtQP_FOT::getLb(const ElInfo *elInfo, int nPoints, - VectorOfFixVecs<DimVec<double> >& Lb) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) { - if (b) - lb(Lambda, *b, Lb[iq], (*f)(coordsAtQPs[iq], vecAtQPs[iq])); - else - l1(Lambda, Lb[iq], (*f)(coordsAtQPs[iq], vecAtQPs[iq])); - } - } - - void FctVecAtQP_FOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - if (grdUhAtQP) - for (int iq = 0; iq < nPoints; iq++) - result[iq] += - fac * (*f)(coordsAtQPs[iq], vecAtQPs[iq]) * ((*b) * grdUhAtQP[iq]); - } - - Vec2AtQP_FOT::Vec2AtQP_FOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, - BinaryAbstractFunction<double, double, double> *af, - WorldVector<double> *b_) - : FirstOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), f(af), b(b_) - { - TEST_EXIT(dv1)("No first vector!\n"); - TEST_EXIT(dv2)("No second vector!\n"); - - auxFeSpaces.insert(dv1->getFESpace()); - auxFeSpaces.insert(dv2->getFESpace()); - } - - Vec2AtQP_FOT::Vec2AtQP_FOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, - BinaryAbstractFunction<double, double, double> *af, - int bIdx) - : FirstOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), f(af) - { - TEST_EXIT(dv1)("No first vector!\n"); - TEST_EXIT(dv2)("No second vector!\n"); - - bOne = bIdx; - auxFeSpaces.insert(dv1->getFESpace()); - auxFeSpaces.insert(dv2->getFESpace()); - } - - void Vec2AtQP_FOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vec1AtQPs = subAssembler->getVectorAtQPs(vec1, elInfo, quad); - vec2AtQPs = subAssembler->getVectorAtQPs(vec2, elInfo, quad); - } - - void Vec2AtQP_FOT::getLb(const ElInfo *elInfo, int nPoints, - VectorOfFixVecs<DimVec<double> >& Lb) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - - if (bOne > -1) { - for (int iq = 0; iq < nPoints; iq++) - lb_one(Lambda, Lb[iq], (*f)(vec1AtQPs[iq], vec2AtQPs[iq])); - } else if (b) { - for (int iq = 0; iq < nPoints; iq++) - lb(Lambda, *b, Lb[iq], (*f)(vec1AtQPs[iq], vec2AtQPs[iq])); - } else { - for (int iq = 0; iq < nPoints; iq++) - l1(Lambda, Lb[iq], (*f)(vec1AtQPs[iq], vec2AtQPs[iq])); - } - } - - void Vec2AtQP_FOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - if (grdUhAtQP) - for (int iq = 0; iq < nPoints; iq++) - result[iq] += fac * (*f)(vec1AtQPs[iq], vec2AtQPs[iq]) * ((*b) * grdUhAtQP[iq]); - } - - - Vec3FctAtQP_FOT::Vec3FctAtQP_FOT(DOFVectorBase<double> *dv1, - DOFVectorBase<double> *dv2, - DOFVectorBase<double> *dv3, - TertiaryAbstractFunction<double, double, double, double> *f_, - WorldVector<double> *bvec) - : FirstOrderTerm(f_->getDegree()), - vec1(dv1), - vec2(dv2), - vec3(dv3), - f(f_), - b(bvec) - { - auxFeSpaces.insert(dv1->getFESpace()); - auxFeSpaces.insert(dv2->getFESpace()); - auxFeSpaces.insert(dv3->getFESpace()); - } - - - Vec3FctAtQP_FOT::Vec3FctAtQP_FOT(DOFVectorBase<double> *dv1, - DOFVectorBase<double> *dv2, - DOFVectorBase<double> *dv3, - TertiaryAbstractFunction<double, double, double, double> *f_, - int b) - : FirstOrderTerm(f_->getDegree()), - vec1(dv1), - vec2(dv2), - vec3(dv3), - f(f_) - { - bOne = b; - auxFeSpaces.insert(dv1->getFESpace()); - auxFeSpaces.insert(dv2->getFESpace()); - auxFeSpaces.insert(dv3->getFESpace()); - } - - void Vec3FctAtQP_FOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vec1AtQPs = subAssembler->getVectorAtQPs(vec1, elInfo, quad); - vec2AtQPs = subAssembler->getVectorAtQPs(vec2, elInfo, quad); - vec3AtQPs = subAssembler->getVectorAtQPs(vec3, elInfo, quad); - } - - - void Vec3FctAtQP_FOT::getLb(const ElInfo *elInfo, int nPoints, - VectorOfFixVecs<DimVec<double> >& Lb) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - if (bOne > -1) { - for (int iq = 0; iq < nPoints; iq++) - lb_one(Lambda, Lb[iq], (*f)(vec1AtQPs[iq], vec2AtQPs[iq], vec3AtQPs[iq])); - } else { - for (int iq = 0; iq < nPoints; iq++) { - if (b) - lb(Lambda, *b, Lb[iq], (*f)(vec1AtQPs[iq], vec2AtQPs[iq], vec3AtQPs[iq])); - else - l1(Lambda, Lb[iq], (*f)(vec1AtQPs[iq], vec2AtQPs[iq], vec3AtQPs[iq])); - } - } - } - - - void Vec3FctAtQP_FOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - if (grdUhAtQP) - for (int iq = 0; iq < nPoints; iq++) - result[iq] += fac * (*f)(vec1AtQPs[iq], vec2AtQPs[iq] ,vec3AtQPs[iq]) * - ((*b) * grdUhAtQP[iq]); - } - - - General_FOT::General_FOT(std::vector<DOFVectorBase<double>*> vecs, - std::vector<DOFVectorBase<double>*> grads, - TertiaryAbstractFunction<WorldVector<double>, - WorldVector<double>, - std::vector<double>, - std::vector<WorldVector<double> > > *af) - : FirstOrderTerm(af->getDegree()), vecs_(vecs), grads_(grads), f_(af) - { - vecsAtQPs_.resize(vecs_.size()); - gradsAtQPs_.resize(grads_.size()); - - for (int i = 0; i < static_cast<int>(vecs.size()); i++) { - TEST_EXIT(vecs[i])("One vector is NULL!\n"); - - auxFeSpaces.insert(vecs[i]->getFESpace()); - } - - for (int i = 0; i < static_cast<int>(grads.size()); i++) { - TEST_EXIT(grads[i])("One gradient vector is NULL!\n"); - - auxFeSpaces.insert(grads[i]->getFESpace()); - } - } - - GeneralParametric_FOT::GeneralParametric_FOT(std::vector<DOFVectorBase<double>*> vecs, - std::vector<DOFVectorBase<double>*> grads, - QuartAbstractFunction<WorldVector<double>, - WorldVector<double>, - WorldVector<double>, - std::vector<double>, - std::vector<WorldVector<double> > > *af) - : FirstOrderTerm(af->getDegree()), vecs_(vecs), grads_(grads), f_(af) - { - vecsAtQPs_.resize(vecs_.size()); - gradsAtQPs_.resize(grads_.size()); - - for (int i = 0; i < static_cast<int>(vecs.size()); i++) { - TEST_EXIT(vecs[i])("One vector is NULL!\n"); - - auxFeSpaces.insert(vecs[i]->getFESpace()); - } - - for (int i = 0; i < static_cast<int>(grads.size()); i++) { - TEST_EXIT(grads[i])("One gradient vector is NULL!\n"); - - auxFeSpaces.insert(grads[i]->getFESpace()); - } - } - - MatrixFct_SOT::MatrixFct_SOT(DOFVectorBase<double> *dv, - AbstractFunction<WorldMatrix<double>, double> *fct, - AbstractFunction<WorldVector<double>, WorldMatrix<double> > *div, - bool sym) - : SecondOrderTerm(fct->getDegree()), - vec(dv), - matrixFct(fct), - divFct(div), - symmetric(sym) - { - setSymmetric(symmetric); - - TEST_EXIT(dv)("No vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - } - - VecAtQP_SOT::VecAtQP_SOT(DOFVectorBase<double> *dv, - AbstractFunction<double, double> *af) - : SecondOrderTerm(af->getDegree()), vec(dv), f(af) - { - setSymmetric(true); - - TEST_EXIT(dv)("No vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - } - - Vec2AtQP_SOT::Vec2AtQP_SOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, - BinaryAbstractFunction<double, double, double> *af) - : SecondOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), f(af) + Assembler *Operator::getAssembler(int rank) { - setSymmetric(true); - - TEST_EXIT(dv1)("No first vector!\n"); - TEST_EXIT(dv2)("No second vector!\n"); + if (!assembler[rank]) + initAssembler(rank, NULL, NULL, NULL, NULL); - auxFeSpaces.insert(dv1->getFESpace()); - auxFeSpaces.insert(dv2->getFESpace()); + return assembler[rank]; } - MatrixGradient_SOT::MatrixGradient_SOT(DOFVectorBase<double> *dv, - AbstractFunction<WorldMatrix<double>, WorldVector<double> > *af, - AbstractFunction<WorldVector<double>, WorldMatrix<double> > *divAf, - bool symm) - : SecondOrderTerm(af->getDegree()), - vec(dv), - f(af), - divFct(divAf), - gradAtQPs(NULL), - symmetric(symm) + void Operator::setAssembler(int rank, Assembler *a) { - setSymmetric(symmetric); - - TEST_EXIT(dv)("No vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - } - - FctGradient_SOT::FctGradient_SOT(DOFVectorBase<double> *dv, - AbstractFunction<double, WorldVector<double> > *af) - : SecondOrderTerm(af->getDegree()), vec(dv), f(af) - { - TEST_EXIT(dv)("No vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - } - - VecMatrixGradientAtQP_SOT::VecMatrixGradientAtQP_SOT(DOFVectorBase<double> *dv, - BinaryAbstractFunction<WorldMatrix<double>, double, WorldVector<double> > *af, - AbstractFunction<WorldVector<double>, WorldMatrix<double> > *divAf, - bool symm) - : SecondOrderTerm(af->getDegree()), vec(dv), f(af), - divFct(divAf), symmetric(symm) - { - setSymmetric(symmetric); - - TEST_EXIT(dv)("No vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - } - - VecGradCoordsAtQP_SOT::VecGradCoordsAtQP_SOT(DOFVectorBase<double> *dv, - TertiaryAbstractFunction<double, double, - WorldVector<double>, WorldVector<double> > *af) - : SecondOrderTerm(af->getDegree()), vec(dv), f(af) - { - TEST_EXIT(dv)("No vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - } - - VecAndCoordsAtQP_SOT::VecAndCoordsAtQP_SOT(DOFVectorBase<double> *dv, - BinaryAbstractFunction<double, double, WorldVector<double> > *af) - : SecondOrderTerm(af->getDegree()), vec(dv), f(af) - { - setSymmetric(true); - - TEST_EXIT(dv)("No vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - } - - MatrixGradientAndCoords_SOT::MatrixGradientAndCoords_SOT(DOFVectorBase<double> *dv, - BinaryAbstractFunction<WorldMatrix<double>, - WorldVector<double>, WorldVector<double> > *af, - AbstractFunction<WorldVector<double>, - WorldMatrix<double> > *divAf, - bool symm) - : SecondOrderTerm(af->getDegree()), vec(dv), f(af), divFct(divAf), symmetric(symm) - { - setSymmetric(symmetric); - - TEST_EXIT(dv)("No vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - } - - - MatrixVec2_SOT::MatrixVec2_SOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, - BinaryAbstractFunction<double, double, double> *f, - WorldMatrix<double> Af, - bool sym) - : SecondOrderTerm(f->getDegree()), - vec1(dv1), - vec2(dv2), - fct(f), - A(Af), - symmetric(sym) - { - FUNCNAME("MatrixVec2_SOT::MatrixVec2_SOT()"); - - setSymmetric(symmetric); - - TEST_EXIT_DBG(dv1)("No vector!\n"); - TEST_EXIT_DBG(dv2)("No vector!\n"); - - auxFeSpaces.insert(dv1->getFESpace()); - auxFeSpaces.insert(dv2->getFESpace()); - } - - void MatrixVec2_SOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vec1AtQPs = getVectorAtQPs(vec1, elInfo, subAssembler, quad); - vec2AtQPs = getVectorAtQPs(vec2, elInfo, subAssembler, quad); - } - - void MatrixVec2_SOT::getLALt(const ElInfo *elInfo, int nPoints, - DimMat<double> **LALt) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - lalt(Lambda, A, *(LALt[iq]), symmetric, (*fct)(vec1AtQPs[iq], vec2AtQPs[iq])); - } - - void MatrixVec2_SOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor) - { - int dow = Global::getGeo(WORLD); - - for (int iq = 0; iq < nPoints; iq++) { - double resultQP = 0.0; - - if (D2UhAtQP) - for (int i = 0; i < dow; i++) - for (int j = 0; j < dow; j++) - resultQP += A[i][j] * D2UhAtQP[iq][j][i]; - - result[iq] += resultQP * factor * (*fct)(vec1AtQPs[iq], vec2AtQPs[iq]); - } - } - - void MatrixVec2_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - int nPoints = grdUhAtQP.size(); - for (int iq = 0; iq < nPoints; iq++) - result[iq] += A * grdUhAtQP[iq] * (*fct)(vec1AtQPs[iq], vec2AtQPs[iq]); - } - - General_SOT::General_SOT(std::vector<DOFVectorBase<double>*> vecs, - std::vector<DOFVectorBase<double>*> grads, - TertiaryAbstractFunction<WorldMatrix<double>, - WorldVector<double>, - std::vector<double>, - std::vector<WorldVector<double> > > *f, - AbstractFunction<WorldVector<double>, - WorldMatrix<double> > *divFct, - bool symmetric) - : SecondOrderTerm(f->getDegree()), - vecs_(vecs), - grads_(grads), - f_(f), - divFct_(divFct), - symmetric_(symmetric) - { - vecsAtQPs_.resize(vecs_.size()); - gradsAtQPs_.resize(grads_.size()); - - for (int i = 0; i < static_cast<int>(vecs.size()); i++) { - TEST_EXIT(vecs[i])("One vector is NULL!\n"); - - auxFeSpaces.insert(vecs[i]->getFESpace()); - } - - for (int i = 0; i < static_cast<int>(grads.size()); i++) { - TEST_EXIT(grads[i])("One gradient vector is NULL!\n"); - - auxFeSpaces.insert(grads[i]->getFESpace()); - } - } - - GeneralParametric_SOT::GeneralParametric_SOT(std::vector<DOFVectorBase<double>*> vecs, - std::vector<DOFVectorBase<double>*> grads, - QuartAbstractFunction<WorldMatrix<double>, - WorldVector<double>, - WorldVector<double>, - std::vector<double>, - std::vector<WorldVector<double> > > *f, - AbstractFunction<WorldVector<double>, - WorldMatrix<double> > *divFct, - bool symmetric) - : SecondOrderTerm(f->getDegree()), - vecs_(vecs), - grads_(grads), - f_(f), - divFct_(divFct), - symmetric_(symmetric) - { - vecsAtQPs_.resize(vecs_.size()); - gradsAtQPs_.resize(grads_.size()); - - for (int i = 0; i < static_cast<int>(vecs.size()); i++) { - TEST_EXIT(vecs[i])("One vector is NULL!\n"); - - auxFeSpaces.insert(vecs[i]->getFESpace()); - } - - for (int i = 0; i < static_cast<int>(grads.size()); i++) { - TEST_EXIT(grads[i])("One gradient vector is NULL!\n"); - - auxFeSpaces.insert(grads[i]->getFESpace()); - } - } - - VecAndGradAtQP_SOT::VecAndGradAtQP_SOT(DOFVectorBase<double> *dv, - BinaryAbstractFunction<double, double, WorldVector<double> > *af) - : SecondOrderTerm(af->getDegree()), vec(dv), f(af) - { - TEST_EXIT(dv)("No vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - } - - VecAtQP_IJ_SOT::VecAtQP_IJ_SOT(DOFVectorBase<double> *dv, - AbstractFunction<double, double> *af, - int x_i, int x_j) - : SecondOrderTerm(af->getDegree()), vec(dv), f(af), xi(x_i), xj(x_j) - { - setSymmetric(xi == xj); - - TEST_EXIT(dv)("No vector!\n"); - - auxFeSpaces.insert(dv->getFESpace()); - } - - void MatrixFct_SOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); - } - - void VecAtQP_SOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature* quad) - { - vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); - } - - void VecAtQP_SOT::initElement(const ElInfo* smallElInfo, - const ElInfo* largeElInfo, - SubAssembler* subAssembler, - Quadrature* quad) - { - vecAtQPs = getVectorAtQPs(vec, smallElInfo, largeElInfo, subAssembler, quad); - } - - void Vec2AtQP_SOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs1 = getVectorAtQPs(vec1, elInfo, subAssembler, quad); - vecAtQPs2 = getVectorAtQPs(vec2, elInfo, subAssembler, quad); - } - - void CoordsAtQP_SOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); - } - - void MatrixGradient_SOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); - } - - void MatrixGradient_SOT::initElement(const ElInfo* smallElInfo, - const ElInfo* largeElInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - gradAtQPs = getGradientsAtQPs(vec, smallElInfo, largeElInfo, subAssembler, quad); - } - - void FctGradient_SOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); - } - - void VecMatrixGradientAtQP_SOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); - gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); - } - - void VecAndCoordsAtQP_SOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); - coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); - } - - void MatrixGradientAndCoords_SOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); - coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); - } - - void VecGradCoordsAtQP_SOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); - gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); - coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); - } - - void VecAtQP_FOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); - } - - void CoordsAtQP_FOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); - } - - void VecCoordsAtQP_FOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); - } - - void VectorGradient_FOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); - } - - void VectorFct_FOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); - } - - void VecFctAtQP_FOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); - } - - void VecAtQP_ZOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); - } - - void VecAtQP_ZOT::initElement(const ElInfo* smallElInfo, - const ElInfo* largeElInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs = getVectorAtQPs(vec, smallElInfo, largeElInfo, subAssembler, quad); - } - - - void MultVecAtQP_ZOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs1 = getVectorAtQPs(vec1, elInfo, subAssembler, quad); - vecAtQPs2 = getVectorAtQPs(vec2, elInfo, subAssembler, quad); - } - - void Vec2AtQP_ZOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs1 = getVectorAtQPs(vec1, elInfo, subAssembler, quad); - vecAtQPs2 = getVectorAtQPs(vec2, elInfo, subAssembler, quad); - } - - void Vec2AtQP_ZOT::initElement(const ElInfo* smallElInfo, - const ElInfo* largeElInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - TEST_EXIT(vec1->getFESpace() == vec2->getFESpace())("Not yet implemented!\n"); - - vecAtQPs1 = getVectorAtQPs(vec1, smallElInfo, largeElInfo, subAssembler, quad); - vecAtQPs2 = getVectorAtQPs(vec2, smallElInfo, largeElInfo, subAssembler, quad); - } - - void Vec3AtQP_ZOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs1 = getVectorAtQPs(vec1, elInfo, subAssembler, quad); - vecAtQPs2 = getVectorAtQPs(vec2, elInfo, subAssembler, quad); - vecAtQPs3 = getVectorAtQPs(vec3, elInfo, subAssembler, quad); - } - - void VecAndCoordsAtQP_ZOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); - coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); - } - - void Vec2AndGradAtQP_ZOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs1 = getVectorAtQPs(vec1, elInfo, subAssembler, quad); - vecAtQPs2 = getVectorAtQPs(vec2, elInfo, subAssembler, quad); - gradAtQPs = getGradientsAtQPs(vec1, elInfo, subAssembler, quad); - } - - void FctGradientCoords_ZOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); - coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); - } - - void VecGradCoordsAtQP_ZOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); - gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); - coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); - } - - void VecAndGradAtQP_ZOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); - gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); - } - - void VecAndGradVecAtQP_ZOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); - gradAtQPs = getGradientsAtQPs(vecGrd, elInfo, subAssembler, quad); - } - - void VecAndGradVec2AtQP_ZOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); - grad1AtQPs = getGradientsAtQPs(vecGrd1, elInfo, subAssembler, quad); - grad2AtQPs = getGradientsAtQPs(vecGrd2, elInfo, subAssembler, quad); - } - - void FctGradient_ZOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); - } - - void CoordsAtQP_ZOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); - } - - void MatrixFct_SOT::getLALt(const ElInfo *elInfo, int nPoints, - DimMat<double> **LALt) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - lalt(Lambda, (*matrixFct)(vecAtQPs[iq]), *(LALt[iq]), symmetric, 1.0); - } - - void VecAtQP_SOT::getLALt(const ElInfo *elInfo, int nPoints, - DimMat<double> **LALt) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - l1lt(Lambda, *(LALt[iq]), (*f)(vecAtQPs[iq])); - } - - void Vec2AtQP_SOT::getLALt(const ElInfo *elInfo, int nPoints, - DimMat<double> **LALt) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - l1lt(Lambda, *(LALt[iq]), (*f)(vecAtQPs1[iq], vecAtQPs2[iq])); - } - - void CoordsAtQP_SOT::getLALt(const ElInfo *elInfo, int nPoints, - DimMat<double> **LALt) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - l1lt(Lambda, (*LALt[iq]), (*g)(coordsAtQPs[iq])); - } - - void MatrixGradient_SOT::getLALt(const ElInfo *elInfo, int nPoints, - DimMat<double> **LALt) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - lalt(Lambda, (*f)(gradAtQPs[iq]), (*LALt[iq]), symmetric, 1.0); - } - - void FctGradient_SOT::getLALt(const ElInfo *elInfo, int nPoints, - DimMat<double> **LALt) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - l1lt(Lambda, *(LALt[iq]), (*f)(gradAtQPs[iq])); - } - - void VecMatrixGradientAtQP_SOT::getLALt(const ElInfo *elInfo, int nPoints, - DimMat<double> **LALt) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - lalt(Lambda, (*f)(vecAtQPs[iq], gradAtQPs[iq]), (*LALt[iq]), symmetric, 1.0); - } - - void VecAndCoordsAtQP_SOT::getLALt(const ElInfo *elInfo, int nPoints, - DimMat<double> **LALt) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - l1lt(Lambda, *(LALt[iq]), (*f)(vecAtQPs[iq], coordsAtQPs[iq])); - } - - void MatrixGradientAndCoords_SOT::getLALt(const ElInfo *elInfo, int nPoints, - DimMat<double> **LALt) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - lalt(Lambda, (*f)(gradAtQPs[iq], coordsAtQPs[iq]), (*LALt[iq]), symmetric, 1.0); - } - - void VecGradCoordsAtQP_SOT::getLALt(const ElInfo *elInfo, int nPoints, - DimMat<double> **LALt) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - l1lt(Lambda, *(LALt[iq]), (*f)(vecAtQPs[iq], gradAtQPs[iq], coordsAtQPs[iq])); - } - - void VecAtQP_FOT::getLb(const ElInfo *elInfo, int nPoints, - VectorOfFixVecs<DimVec<double> >& Lb) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - - if (bOne > -1) { - for (int iq = 0; iq < nPoints; iq++) - lb_one(Lambda, Lb[iq], (*f)(vecAtQPs[iq])); - } else if (b) { - for (int iq = 0; iq < nPoints; iq++) - lb(Lambda, *b, Lb[iq], (*f)(vecAtQPs[iq])); - } else { - for (int iq = 0; iq < nPoints; iq++) - l1(Lambda, Lb[iq], (*f)(vecAtQPs[iq])); - } - } - - void CoordsAtQP_FOT::getLb(const ElInfo *elInfo, int nPoints, - VectorOfFixVecs<DimVec<double> >& Lb) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - l1(Lambda, Lb[iq], (*g)(coordsAtQPs[iq])); - } - - void VecCoordsAtQP_FOT::getLb(const ElInfo *elInfo, int nPoints, - VectorOfFixVecs<DimVec<double> >& Lb) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - lb(Lambda, b, Lb[iq], (*g)(coordsAtQPs[iq])); - } - - void VectorGradient_FOT::getLb(const ElInfo *elInfo, int nPoints, - VectorOfFixVecs<DimVec<double> >& Lb) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - if (f) { - for (int iq = 0; iq < nPoints; iq++) - lb(Lambda, (*f)(gradAtQPs[iq]), Lb[iq], 1.0); - } else { - for (int iq = 0; iq < nPoints; iq++) - lb(Lambda, gradAtQPs[iq], Lb[iq], 1.0); - } - } - - void VectorFct_FOT::getLb(const ElInfo *elInfo, int nPoints, - VectorOfFixVecs<DimVec<double> >& Lb) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - lb(Lambda, (*vecFct)(vecAtQPs[iq]), Lb[iq], 1.0); - } - - void VecFctAtQP_FOT::getLb(const ElInfo *elInfo, int nPoints, - VectorOfFixVecs<DimVec<double> >& Lb) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - lb(Lambda, (*g)(coordsAtQPs[iq]), Lb[iq], 1.0); - } - - void VecAtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) - { - if (f) { - for (int iq = 0; iq < nPoints; iq++) - C[iq] += (*f)(vecAtQPs[iq]); - } else { - for (int iq = 0; iq < nPoints; iq++) - C[iq] += vecAtQPs[iq]; - } - } - - void VecAtQP_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - if (f) { - for (int iq = 0; iq < nPoints; iq++) - result[iq] += fac * (*f)(vecAtQPs[iq]) * uhAtQP[iq]; - } else { - for (int iq = 0; iq < nPoints; iq++) - result[iq] += fac * vecAtQPs[iq] * uhAtQP[iq]; - } - } - - - void MultVecAtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) - { - for (int iq = 0; iq < nPoints; iq++) - C[iq] += (*f1)(vecAtQPs1[iq]) * (*f2)(vecAtQPs2[iq]); - } - - void MultVecAtQP_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - for (int iq = 0; iq < nPoints; iq++) - result[iq] += fac * (*f1)(vecAtQPs1[iq]) * (*f2)(vecAtQPs2[iq]) * uhAtQP[iq]; - } - - void Vec2AtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) - { - for (int iq = 0; iq < nPoints; iq++) - C[iq] += (*f)(vecAtQPs1[iq], vecAtQPs2[iq]); - } - - void Vec2AtQP_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - for (int iq = 0; iq < nPoints; iq++) - result[iq] += fac * (*f)(vecAtQPs1[iq], vecAtQPs2[iq]) * uhAtQP[iq]; - } - - void Vec3AtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) - { - for (int iq = 0; iq < nPoints; iq++) - C[iq] += (*f)(vecAtQPs1[iq], vecAtQPs2[iq], vecAtQPs3[iq]); - } - - void Vec3AtQP_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - for (int iq = 0; iq < nPoints; iq++) - result[iq] += - fac * (*f)(vecAtQPs1[iq], vecAtQPs2[iq], vecAtQPs3[iq]) * uhAtQP[iq]; - } - - - void VecAndCoordsAtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) - { - for (int iq = 0; iq < nPoints; iq++) - C[iq] += (*f)(vecAtQPs[iq], coordsAtQPs[iq]); - } - - void VecAndCoordsAtQP_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - for (int iq = 0; iq < nPoints; iq++) - result[iq] += fac * (*f)(vecAtQPs[iq], coordsAtQPs[iq]) * uhAtQP[iq]; - } - - - void FctGradientCoords_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) - { - for (int iq = 0; iq < nPoints; iq++) - C[iq] += (*f)(gradAtQPs[iq], coordsAtQPs[iq]); - } - - void FctGradientCoords_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - for (int iq = 0; iq < nPoints; iq++) - result[iq] += - fac * (*f)(gradAtQPs[iq], coordsAtQPs[iq]) * uhAtQP[iq]; - } - - void VecGradCoordsAtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) - { - for (int iq = 0; iq < nPoints; iq++) - C[iq] += (*f)(vecAtQPs[iq], gradAtQPs[iq], coordsAtQPs[iq]); - } - - void VecGradCoordsAtQP_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - for (int iq = 0; iq < nPoints; iq++) - result[iq] += - fac * - (*f)(vecAtQPs[iq], gradAtQPs[iq], coordsAtQPs[iq]) * - uhAtQP[iq]; - } - - void Vec2AndGradAtQP_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - for (int iq = 0; iq < nPoints; iq++) - result[iq] += - fac * - (*f)(vecAtQPs1[iq], gradAtQPs[iq], vecAtQPs2[iq]) * - uhAtQP[iq]; - } - - void Vec2AndGradAtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) - { - for (int iq = 0; iq < nPoints; iq++) - C[iq] += (*f)(vecAtQPs1[iq], gradAtQPs[iq], vecAtQPs2[iq]); - } - - void VecAndGradAtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) - { - for (int iq = 0; iq < nPoints; iq++) - C[iq] += (*f)(vecAtQPs[iq], gradAtQPs[iq]); - } - - void VecAndGradAtQP_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - for (int iq = 0; iq < nPoints; iq++) - result[iq] += fac * (*f)(vecAtQPs[iq], gradAtQPs[iq]) * uhAtQP[iq]; - } - - void VecAndGradVecAtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) - { - for (int iq = 0; iq < nPoints; iq++) - C[iq] += (*f)(vecAtQPs[iq], gradAtQPs[iq]); - } - - void VecAndGradVecAtQP_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - for (int iq = 0; iq < nPoints; iq++) - result[iq] += fac * (*f)(vecAtQPs[iq], gradAtQPs[iq]) * uhAtQP[iq]; - } - - void VecAndGradVec2AtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) - { - for (int iq = 0; iq < nPoints; iq++) - C[iq] += (*f)(vecAtQPs[iq], grad1AtQPs[iq], grad2AtQPs[iq]); - } - - void VecAndGradVec2AtQP_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - for (int iq = 0; iq < nPoints; iq++) - result[iq] += - fac * (*f)(vecAtQPs[iq], grad1AtQPs[iq], grad2AtQPs[iq]) * uhAtQP[iq]; - } - - void FctGradient_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) - { - for (int iq = 0; iq < nPoints; iq++) - C[iq] += (*f)(gradAtQPs[iq]); - } - - void FctGradient_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - for (int iq = 0; iq < nPoints; iq++) - result[iq] += fac * (*f)(gradAtQPs[iq]) * uhAtQP[iq]; - } - - void CoordsAtQP_ZOT::getC(const ElInfo *elInfo, int nPoints, std::vector<double> &C) - { - for (int iq = 0; iq < nPoints; iq++) - C[iq] += (*g)(coordsAtQPs[iq]); - } - - void CoordsAtQP_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - for (int iq = 0; iq < nPoints; iq++) - result[iq] += fac * (*g)(coordsAtQPs[iq]) * uhAtQP[iq]; - } - - void MatrixFct_SOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor) - { - int dow = Global::getGeo(WORLD); - - for (int iq = 0; iq < nPoints; iq++) { - double resultQP = 0.0; - - WorldMatrix<double> A = (*matrixFct)(vecAtQPs[iq]); - - if (D2UhAtQP) - for (int i = 0; i < dow; i++) - for (int j = 0; j < dow; j++) - resultQP += A[i][j] * D2UhAtQP[iq][j][i]; - - if (grdUhAtQP) - resultQP += (*divFct)(A) * grdUhAtQP[iq]; - - result[iq] += resultQP * factor; - } - } - - void MatrixFct_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - int nPoints = grdUhAtQP.size(); - WorldMatrix<double> A; - for (int iq = 0; iq < nPoints; iq++) { - A = (*matrixFct)(vecAtQPs[iq]); - result[iq] += A * grdUhAtQP[iq]; - } - } - - - void Matrix_SOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor) - { - int dow = Global::getGeo(WORLD); - - if (D2UhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - double resultQP = 0.0; - for (int i = 0; i < dow; i++) - for (int j = 0; j < dow; j++) - resultQP += matrix[i][j] * D2UhAtQP[iq][j][i]; - - result[iq] += resultQP * factor; - } - } - } - - void Matrix_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - int nPoints = grdUhAtQP.size(); - for (int iq = 0; iq < nPoints; iq++) - result[iq] += matrix * grdUhAtQP[iq]; - } - - void MatrixGradient_SOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor) - { - int dow = Global::getGeo(WORLD); - - for (int iq = 0; iq < nPoints; iq++) { - double resultQP = 0.0; - - WorldMatrix<double> A = (*f)(gradAtQPs[iq]); - - if (D2UhAtQP) - for (int i = 0; i < dow; i++) - for (int j = 0; j < dow; j++) - resultQP += A[i][j] * D2UhAtQP[iq][j][i]; - - if (grdUhAtQP) - resultQP += (*divFct)(A) * grdUhAtQP[iq]; - - result[iq] += resultQP * factor; - } - } - - - void MatrixGradient_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - FUNCNAME("MatrixGradient_SOT::weakEval()"); - - TEST_EXIT_DBG(f)("No function f!\n"); - TEST_EXIT_DBG(gradAtQPs)("Operator was not initialized correctly!\n"); - - int nPoints = grdUhAtQP.size(); - for (int iq = 0; iq < nPoints; iq++) { - tmpMat = (*f)(gradAtQPs[iq]); - result[iq] += tmpMat * grdUhAtQP[iq]; - } - } - - - void VecAtQP_SOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - int dow = Global::getGeo(WORLD); - - if (D2UhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*f)(vecAtQPs[iq]); - double resultQP = 0.0; - for (int i = 0; i < dow; i++) - resultQP += D2UhAtQP[iq][i][i]; - result[iq] += fac * factor * resultQP; - } - } - } - - void VecAtQP_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - int nPoints = grdUhAtQP.size(); - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*f)(vecAtQPs[iq]); - axpy(factor, grdUhAtQP[iq], result[iq]); - } - } - - void Vec2AtQP_SOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - int dow = Global::getGeo(WORLD); - - if (D2UhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*f)(vecAtQPs1[iq], vecAtQPs2[iq]); - double resultQP = 0.0; - for (int i = 0; i < dow; i++) - resultQP += D2UhAtQP[iq][i][i]; - result[iq] += fac * factor * resultQP; - } - } - } - - void Vec2AtQP_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - int nPoints = grdUhAtQP.size(); - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*f)(vecAtQPs1[iq], vecAtQPs2[iq]); - axpy(factor, grdUhAtQP[iq], result[iq]); - } - } - - void CoordsAtQP_SOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double f) - { - int dow = Global::getGeo(WORLD); - - if (D2UhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*g)(coordsAtQPs[iq]); - double resultQP = 0.0; - for (int i = 0; i < dow; i++) - resultQP += D2UhAtQP[iq][i][i]; - result[iq] += factor * f * resultQP; - } - } - } - - void CoordsAtQP_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - int nPoints = grdUhAtQP.size(); - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*g)(coordsAtQPs[iq]); - axpy(factor, grdUhAtQP[iq], result[iq]); - } - } - - void FctGradient_SOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - int dow = Global::getGeo(WORLD); - - if (D2UhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*f)(gradAtQPs[iq]); - double resultQP = 0.0; - for (int i = 0; i < dow; i++) - resultQP += D2UhAtQP[iq][i][i]; - result[iq] += fac * factor * resultQP; - } - } - } - - void FctGradient_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - int nPoints = grdUhAtQP.size(); - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*f)(gradAtQPs[iq]); - axpy(factor, grdUhAtQP[iq], result[iq]); - } - } - - void VecMatrixGradientAtQP_SOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor) - { - int dow = Global::getGeo(WORLD); - - for (int iq = 0; iq < nPoints; iq++) { - double resultQP = 0.0; - - WorldMatrix<double> A = (*f)(vecAtQPs[iq], gradAtQPs[iq]); - - if (D2UhAtQP) - for (int i = 0; i < dow; i++) - for (int j = 0; j < dow; j++) - resultQP += A[i][j] * D2UhAtQP[iq][j][i]; - - if (grdUhAtQP) - resultQP += (*divFct)(A) * grdUhAtQP[iq]; - - result[iq] += resultQP * factor; - } - } - - void VecMatrixGradientAtQP_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - int nPoints = grdUhAtQP.size(); - WorldMatrix<double> A; - for (int iq = 0; iq < nPoints; iq++) { - A = (*f)(vecAtQPs[iq], gradAtQPs[iq]); - result[iq] += A * grdUhAtQP[iq]; - } - } - - void VecAndCoordsAtQP_SOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - int dow = Global::getGeo(WORLD); - - if (D2UhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*f)(vecAtQPs[iq], coordsAtQPs[iq]); - double resultQP = 0.0; - for (int i = 0; i < dow; i++) - resultQP += D2UhAtQP[iq][i][i]; - result[iq] += fac * factor * resultQP; - } - } - } - - void VecAndCoordsAtQP_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - int nPoints = grdUhAtQP.size(); - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*f)(vecAtQPs[iq], coordsAtQPs[iq]); - axpy(factor, grdUhAtQP[iq], result[iq]); - } - } - - void MatrixGradientAndCoords_SOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor) - { - int dow = Global::getGeo(WORLD); - - for (int iq = 0; iq < nPoints; iq++) { - double resultQP = 0.0; - - WorldMatrix<double> A = (*f)(gradAtQPs[iq], coordsAtQPs[iq]); - - if (D2UhAtQP) - for (int i = 0; i < dow; i++) - for (int j = 0; j < dow; j++) - resultQP += A[i][j] * D2UhAtQP[iq][j][i]; - - if (grdUhAtQP) - resultQP += (*divFct)(A) * grdUhAtQP[iq]; - - result[iq] += resultQP * factor; - } - } - - void MatrixGradientAndCoords_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - int nPoints = grdUhAtQP.size(); - WorldMatrix<double> A; - for (int iq = 0; iq < nPoints; iq++) { - A = (*f)(gradAtQPs[iq], coordsAtQPs[iq]); - result[iq] += A * grdUhAtQP[iq]; - } - } - - void VecGradCoordsAtQP_SOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - int dow = Global::getGeo(WORLD); - - if (D2UhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq], coordsAtQPs[iq]); - double resultQP = 0.0; - for (int i = 0; i < dow; i++) - resultQP += D2UhAtQP[iq][i][i]; - result[iq] += fac * factor * resultQP; - } - } - } - - void VecGradCoordsAtQP_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - int nPoints = grdUhAtQP.size(); - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq], coordsAtQPs[iq]); - axpy(factor, grdUhAtQP[iq], result[iq]); - } - } - - void VecAtQP_FOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - int dow = Global::getGeo(WORLD); - - if (grdUhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*f)(vecAtQPs[iq]); - double resultQP = 0.0; - for (int i = 0; i < dow; i++) - resultQP += grdUhAtQP[iq][i]; - result[iq] += fac * factor * resultQP; - } - } - } - - void CoordsAtQP_FOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double f) - { - int dow = Global::getGeo(WORLD); - - if (grdUhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*g)(coordsAtQPs[iq]); - double resultQP = 0.0; - for (int i = 0; i < dow; i++) - resultQP += grdUhAtQP[iq][i]; - result[iq] += f * factor * resultQP; - } - } - } - - void VecCoordsAtQP_FOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double f) - { - int dow = Global::getGeo(WORLD); - - if (grdUhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*g)(coordsAtQPs[iq]); - double resultQP = 0.0; - for (int i = 0; i < dow; i++) - resultQP += grdUhAtQP[iq][i]; - - result[iq] += f * factor * resultQP; - } - } - } - - void VectorGradient_FOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor) - { - if (grdUhAtQP) { - if (f) { - for (int iq = 0; iq < nPoints; iq++) { - WorldVector<double> b = (*f)(gradAtQPs[iq]); - result[iq] += b * grdUhAtQP[iq] * factor; - } - } else { - for (int iq = 0; iq < nPoints; iq++) - result[iq] += gradAtQPs[iq] * grdUhAtQP[iq] * factor; - } - } - } - - void VectorFct_FOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor) - { - if (grdUhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - WorldVector<double> b = (*vecFct)(vecAtQPs[iq]); - result[iq] += b * grdUhAtQP[iq] * factor; - } - } - } - - void VecFctAtQP_FOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double f) - { - int dow = Global::getGeo(WORLD); - - if (grdUhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - double resultQP = 0.0; - const WorldVector<double> &b = (*g)(coordsAtQPs[iq]); - for (int i = 0; i < dow; i++) - resultQP += b[i] * grdUhAtQP[iq][i]; - result[iq] += f * resultQP; - } - } - } - - Assembler *Operator::getAssembler(int rank) - { - if (!assembler[rank]) - initAssembler(rank, NULL, NULL, NULL, NULL); - - return assembler[rank]; - } - - void Operator::setAssembler(int rank, Assembler *a) - { - assembler[rank] = a; - } - - void CoordsAtQP_IJ_SOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); - } - - void CoordsAtQP_IJ_SOT::getLALt(const ElInfo *elInfo, - int nPoints, - DimMat<double> **LALt) const - { - const DimVec<WorldVector<double> > Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - lalt_kl(Lambda, xi, xj, *(LALt[iq]), (*g)(coordsAtQPs[iq])); - } - - void CoordsAtQP_IJ_SOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double f) - { - if (D2UhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*g)(coordsAtQPs[iq]); - result[iq] += D2UhAtQP[iq][xi][xj] * factor * f; - } - } - } - - void CoordsAtQP_IJ_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - int nPoints = grdUhAtQP.size(); - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*g)(coordsAtQPs[iq]); - result[iq][xi] += grdUhAtQP[iq][xj] * factor; - } - } - - void VecAtQP_IJ_SOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); - } - - void VecAtQP_IJ_SOT::getLALt(const ElInfo *elInfo, - int nPoints, - DimMat<double> **LALt) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) { - lalt_kl(Lambda, xi, xj, *(LALt[iq]), (*f)(vecAtQPs[iq])); - } - } - - void VecAtQP_IJ_SOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - if (D2UhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*f)(vecAtQPs[iq]); - result[iq] += D2UhAtQP[iq][xi][xj] * factor * fac; - } - } - } - - void VecAtQP_IJ_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - int nPoints = grdUhAtQP.size(); - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*f)(vecAtQPs[iq]); - result[iq][xi] += grdUhAtQP[iq][xj] * factor; - } - } - - - void VecOfDOFVecsAtQP_ZOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - int size = static_cast<int>(vecs.size()); - for (int i = 0; i < size; i++) - vecsAtQPs[i] = getVectorAtQPs(vecs[i], elInfo, subAssembler, quad); - } - - void VecOfDOFVecsAtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) - { - int size = static_cast<int>(vecs.size()); - std::vector<double> arg(size); - - for (int iq = 0; iq < nPoints; iq++) { - for (int i = 0; i < size; i++) - arg[i] = vecsAtQPs[i][iq]; - - C[iq] += (*f)(arg); - } - } - - void VecOfDOFVecsAtQP_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - int size = static_cast<int>(vecs.size()); - std::vector<double> arg(size); - - for (int iq = 0; iq < nPoints; iq++) { - for (int i = 0; i < size; i++) - arg[i] = vecsAtQPs[i][iq]; - - result[iq] += fac * (*f)(arg) * uhAtQP[iq]; - } - } - - - void VecOfGradientsAtQP_ZOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - int size = static_cast<int>(vecs.size()); - for (int i = 0; i < size; i++) - gradsAtQPs[i] = getGradientsAtQPs(vecs[i], elInfo, subAssembler, quad); - } - - void VecDivergence_ZOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - int size = static_cast<int>(vecs.size()); - for (int i = 0; i < size; i++) - gradsAtQPs[i] = getGradientsAtQPs(vecs[i], elInfo, subAssembler, quad); - } - - - void VecOfGradientsAtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) - { - int size = static_cast<int>(vecs.size()); - std::vector<WorldVector<double>*> arg(size); - - for (int iq = 0; iq < nPoints; iq++) { - for (int i = 0; i < size; i++) - arg[i] = &(gradsAtQPs[i][iq]); - - C[iq] += (*f)(arg); - } - } - - void VecOfGradientsAtQP_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - int size = static_cast<int>(vecs.size()); - std::vector<WorldVector<double>*> arg(size); - - for (int iq = 0; iq < nPoints; iq++) { - for (int i = 0; i < size; i++) - arg[i] = &(gradsAtQPs[i][iq]); - - result[iq] += fac * (*f)(arg) * uhAtQP[iq]; - } - } - - void VecDivergence_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) - { - int size = static_cast<int>(vecs.size()); - - for (int iq = 0; iq < nPoints; iq++) - for (int i = 0; i < size; i++) - C[iq] += gradsAtQPs[i][iq][i]; - } - - void VecDivergence_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - int size = static_cast<int>(vecs.size()); - - for (int iq = 0; iq < nPoints; iq++) { - double d = 0.0; - for (int i = 0; i < size; i++) - d += gradsAtQPs[i][iq][i]; - - result[iq] += d * uhAtQP[iq] * fac; - } - } - - void VecAndGradAtQP_SOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - int dow = Global::getGeo(WORLD); - - if (D2UhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq]); - double resultQP = 0.0; - for (int i = 0; i < dow; i++) - resultQP += D2UhAtQP[iq][i][i]; - - result[iq] += fac * resultQP * factor; - } - } - } - - void VecAndGradAtQP_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - int nPoints = grdUhAtQP.size(); - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq]); - axpy(factor, grdUhAtQP[iq], result[iq]); - } - } - - void VecAndGradAtQP_SOT::getLALt(const ElInfo *elInfo, int nPoints, - DimMat<double> **LALt) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - l1lt(Lambda, *(LALt[iq]), (*f)(vecAtQPs[iq], gradAtQPs[iq])); - } - - void VecAndGradAtQP_SOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); - gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); + assembler[rank] = a; } - void General_SOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - int nVecs = static_cast<int>(vecs_.size()); - int nGrads = static_cast<int>(grads_.size()); - - coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); - - for (int i = 0; i < nVecs; i++) - vecsAtQPs_[i] = getVectorAtQPs(vecs_[i], elInfo, subAssembler, quad); - for (int i = 0; i < nGrads; i++) - gradsAtQPs_[i] = getGradientsAtQPs(grads_[i], elInfo, subAssembler, quad); - } - - void General_SOT::getLALt(const ElInfo *elInfo, - int nPoints, - DimMat<double> **LALt) const - { - int nVecs = static_cast<int>(vecs_.size()); - int nGrads = static_cast<int>(grads_.size()); - - std::vector<double> vecsArg(nVecs); - std::vector<WorldVector<double> > gradsArg(nGrads); - - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - - for (int iq = 0; iq < nPoints; iq++) { - for (int i = 0; i < nVecs; i++) - vecsArg[i] = vecsAtQPs_[i][iq]; - for (int i = 0; i < nGrads; i++) - gradsArg[i] = gradsAtQPs_[i][iq]; - - lalt(Lambda, (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg), - *(LALt[iq]), symmetric_, 1.0); - } - } - - void General_SOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor) - { - int dow = Global::getGeo(WORLD); - int nVecs = static_cast<int>(vecs_.size()); - int nGrads = static_cast<int>(grads_.size()); - - std::vector<double> vecsArg(nVecs); - std::vector<WorldVector<double> > gradsArg(nGrads); - - for (int iq = 0; iq < nPoints; iq++) { - double resultQP = 0.0; - - for (int i = 0; i < nVecs; i++) - vecsArg[i] = vecsAtQPs_[i][iq]; - for (int i = 0; i < nGrads; i++) - gradsArg[i] = gradsAtQPs_[i][iq]; - - WorldMatrix<double> A = (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg); - - if (D2UhAtQP) { - for (int i = 0; i < dow; i++) - for (int j = 0; j < dow; j++) - resultQP += A[i][j] * D2UhAtQP[iq][j][i]; - } - - if (grdUhAtQP) - resultQP += (*divFct_)(A) * grdUhAtQP[iq]; - - result[iq] += resultQP * factor; - } - } - - void General_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - int nPoints = grdUhAtQP.size(); - int nVecs = static_cast<int>(vecs_.size()); - int nGrads = static_cast<int>(grads_.size()); - - std::vector<double> vecsArg(nVecs); - std::vector<WorldVector<double> > gradsArg(nGrads); - - WorldMatrix<double> A; - for (int iq = 0; iq < nPoints; iq++) { - for (int i = 0; i < nVecs; i++) - vecsArg[i] = vecsAtQPs_[i][iq]; - for (int i = 0; i < nGrads; i++) - gradsArg[i] = gradsAtQPs_[i][iq]; - - A = (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg); - result[iq] += A * grdUhAtQP[iq]; - } - } - - void General_FOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - int nVecs = static_cast<int>(vecs_.size()); - int nGrads = static_cast<int>(grads_.size()); - - coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); - - for (int i = 0; i < nVecs; i++) - vecsAtQPs_[i] = getVectorAtQPs(vecs_[i], elInfo, subAssembler, quad); - for (int i = 0; i < nGrads; i++) - gradsAtQPs_[i] = getGradientsAtQPs(grads_[i], elInfo, subAssembler, quad); - } - - void General_FOT::getLb(const ElInfo *elInfo, - int nPoints, - VectorOfFixVecs<DimVec<double> >& result) const - { - int nVecs = static_cast<int>(vecs_.size()); - int nGrads = static_cast<int>(grads_.size()); - - std::vector<double> vecsArg(nVecs); - std::vector<WorldVector<double> > gradsArg(nGrads); - - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - - for (int iq = 0; iq < nPoints; iq++) { - for (int i = 0; i < nVecs; i++) - vecsArg[i] = vecsAtQPs_[i][iq]; - for (int i = 0; i < nGrads; i++) - gradsArg[i] = gradsAtQPs_[i][iq]; - - lb(Lambda, (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg), - result[iq], 1.0); - } - } - - void General_FOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor) - { - int dow = Global::getGeo(WORLD); - int nVecs = static_cast<int>(vecs_.size()); - int nGrads = static_cast<int>(grads_.size()); - - std::vector<double> vecsArg(nVecs); - std::vector<WorldVector<double> > gradsArg(nGrads); - - if (grdUhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - double resultQP = 0.0; - - for (int i = 0; i < nVecs; i++) - vecsArg[i] = vecsAtQPs_[i][iq]; - for (int i = 0; i < nGrads; i++) - gradsArg[i] = gradsAtQPs_[i][iq]; - - const WorldVector<double> &b = (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg); - - for (int i = 0; i < dow; i++) - resultQP += grdUhAtQP[iq][i] * b[i]; - - result[iq] += factor * resultQP; - } - } - } - - void General_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad) - { - int nVecs = static_cast<int>(vecs_.size()); - int nGrads = static_cast<int>(grads_.size()); - - coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); - - for (int i = 0; i < nVecs; i++) - vecsAtQPs_[i] = getVectorAtQPs(vecs_[i], elInfo, subAssembler, quad); - for (int i = 0; i < nGrads; i++) - gradsAtQPs_[i] = getGradientsAtQPs(grads_[i], elInfo, subAssembler, quad); - } - - void General_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) - { - unsigned int nVecs = vecs_.size(); - unsigned int nGrads = grads_.size(); - - for (int iq = 0; iq < nPoints; iq++) { - for (unsigned int i = 0; i < nVecs; i++) - vecsArg[i] = vecsAtQPs_[i][iq]; - for (unsigned int i = 0; i < nGrads; i++) - gradsArg[i] = gradsAtQPs_[i][iq]; - - C[iq] += (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg); - } - } - - void General_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - unsigned int nVecs = vecs_.size(); - unsigned int nGrads = grads_.size(); - - for (int iq = 0; iq < nPoints; iq++) { - for (unsigned int i = 0; i < nVecs; i++) - vecsArg[i] = vecsAtQPs_[i][iq]; - for (unsigned int i = 0; i < nGrads; i++) - gradsArg[i] = gradsAtQPs_[i][iq]; - - result[iq] += fac * (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg) * uhAtQP[iq]; - } - } - - void GeneralParametric_SOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - int nVecs = static_cast<int>(vecs_.size()); - int nGrads = static_cast<int>(grads_.size()); - - elInfo->getElementNormal(elementNormal_); - coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); - - for (int i = 0; i < nVecs; i++) - vecsAtQPs_[i] = getVectorAtQPs(vecs_[i], elInfo, subAssembler, quad); - for (int i = 0; i < nGrads; i++) - gradsAtQPs_[i] = getGradientsAtQPs(grads_[i], elInfo, subAssembler, quad); - } - - void GeneralParametric_SOT::getLALt(const ElInfo *elInfo, int nPoints, - DimMat<double> **LALt) const - { - int nVecs = static_cast<int>(vecs_.size()); - int nGrads = static_cast<int>(grads_.size()); - - std::vector<double> vecsArg(nVecs); - std::vector<WorldVector<double> > gradsArg(nGrads); - - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - - for (int iq = 0; iq < nPoints; iq++) { - for (int i = 0; i < nVecs; i++) - vecsArg[i] = vecsAtQPs_[i][iq]; - for (int i = 0; i < nGrads; i++) - gradsArg[i] = gradsAtQPs_[i][iq]; - lalt(Lambda, (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg), - *(LALt[iq]), symmetric_, 1.0); - } - } - - void GeneralParametric_SOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor) - { - int dow = Global::getGeo(WORLD); - int nVecs = static_cast<int>(vecs_.size()); - int nGrads = static_cast<int>(grads_.size()); - - std::vector<double> vecsArg(nVecs); - std::vector<WorldVector<double> > gradsArg(nGrads); - - for (int iq = 0; iq < nPoints; iq++) { - double resultQP = 0.0; - - for (int i = 0; i < nVecs; i++) - vecsArg[i] = vecsAtQPs_[i][iq]; - for (int i = 0; i < nGrads; i++) - gradsArg[i] = gradsAtQPs_[i][iq]; - - WorldMatrix<double> A = - (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg); - - if (D2UhAtQP) { - for (int i = 0; i < dow; i++) - for (int j = 0; j < dow; j++) - resultQP += A[i][j] * D2UhAtQP[iq][j][i]; - } - - if (grdUhAtQP) - resultQP += (*divFct_)(A) * grdUhAtQP[iq]; - - result[iq] += resultQP * factor; - } - } - - void GeneralParametric_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - int nPoints = grdUhAtQP.size(); - int nVecs = static_cast<int>(vecs_.size()); - int nGrads = static_cast<int>(grads_.size()); - - std::vector<double> vecsArg(nVecs); - std::vector<WorldVector<double> > gradsArg(nGrads); - - WorldMatrix<double> A; - for (int iq = 0; iq < nPoints; iq++) { - for (int i = 0; i < nVecs; i++) - vecsArg[i] = vecsAtQPs_[i][iq]; - for (int i = 0; i < nGrads; i++) - gradsArg[i] = gradsAtQPs_[i][iq]; - - A = (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg); - result[iq] += A * grdUhAtQP[iq]; - } - } - - void GeneralParametric_FOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - int nVecs = static_cast<int>(vecs_.size()); - int nGrads = static_cast<int>(grads_.size()); - - elInfo->getElementNormal(elementNormal_); - coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); - - for (int i = 0; i < nVecs; i++) - vecsAtQPs_[i] = getVectorAtQPs(vecs_[i], elInfo, subAssembler, quad); - for (int i = 0; i < nGrads; i++) - gradsAtQPs_[i] = getGradientsAtQPs(grads_[i], elInfo, subAssembler, quad); - } - - void GeneralParametric_FOT::getLb(const ElInfo *elInfo, - int nPoints, - VectorOfFixVecs<DimVec<double> >& result) const - { - int nVecs = static_cast<int>(vecs_.size()); - int nGrads = static_cast<int>(grads_.size()); - - std::vector<double> vecsArg(nVecs); - std::vector<WorldVector<double> > gradsArg(nGrads); - - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) { - for (int i = 0; i < nVecs; i++) - vecsArg[i] = vecsAtQPs_[i][iq]; - for (int i = 0; i < nGrads; i++) - gradsArg[i] = gradsAtQPs_[i][iq]; - - lb(Lambda, (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg), result[iq], 1.0); - } - } - - void GeneralParametric_FOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor) - { - int dow = Global::getGeo(WORLD); - int nVecs = static_cast<int>(vecs_.size()); - int nGrads = static_cast<int>(grads_.size()); - - std::vector<double> vecsArg(nVecs); - std::vector<WorldVector<double> > gradsArg(nGrads); - - if (grdUhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - double resultQP = 0.0; - - for (int i = 0; i < nVecs; i++) - vecsArg[i] = vecsAtQPs_[i][iq]; - for (int i = 0; i < nGrads; i++) - gradsArg[i] = gradsAtQPs_[i][iq]; - - const WorldVector<double> &b = (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg); - - for (int i = 0; i < dow; i++) - resultQP += grdUhAtQP[iq][i] * b[i]; - - result[iq] += factor * resultQP; - } - } - } - - void GeneralParametric_ZOT::initElement(const ElInfo* elInfo, SubAssembler* - subAssembler, Quadrature *quad) - { - int nVecs = static_cast<int>(vecs_.size()); - int nGrads = static_cast<int>(grads_.size()); - - elInfo->getElementNormal(elementNormal_); - coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); - - for (int i = 0; i < nVecs; i++) - vecsAtQPs_[i] = getVectorAtQPs(vecs_[i], elInfo, subAssembler, quad); - for (int i = 0; i < nGrads; i++) - gradsAtQPs_[i] = getGradientsAtQPs(grads_[i], elInfo, subAssembler, quad); - } - - void GeneralParametric_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) - { - int nVecs = static_cast<int>(vecs_.size()); - int nGrads = static_cast<int>(grads_.size()); - - std::vector<double> vecsArg(nVecs); - std::vector<WorldVector<double> > gradsArg(nGrads); - - for (int iq = 0; iq < nPoints; iq++) { - for (int i = 0; i < nVecs; i++) - vecsArg[i] = vecsAtQPs_[i][iq]; - for (int i = 0; i < nGrads; i++) - gradsArg[i] = gradsAtQPs_[i][iq]; - - C[iq] += (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg); - } - } - - void GeneralParametric_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - int nVecs = static_cast<int>(vecs_.size()); - int nGrads = static_cast<int>(grads_.size()); - - std::vector<double> vecsArg(nVecs); - std::vector<WorldVector<double> > gradsArg(nGrads); - - for (int iq = 0; iq < nPoints; iq++) { - for (int i = 0; i < nVecs; i++) - vecsArg[i] = vecsAtQPs_[i][iq]; - for (int i = 0; i < nGrads; i++) - gradsArg[i] = gradsAtQPs_[i][iq]; - result[iq] += - fac * (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg) * uhAtQP[iq]; - } - } - - void VecAndVecOfGradientsAtQP_ZOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - int size = static_cast<int>(vecs.size()); - for (int i = 0; i < size; i++) - gradsAtQPs[i] = getGradientsAtQPs(vecs[i], elInfo, subAssembler, quad); - - vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); - } - - void VecAndVecOfGradientsAtQP_ZOT::getC(const ElInfo *, int nPoints, - std::vector<double> &C) - { - int size = static_cast<int>(vecs.size()); - std::vector<WorldVector<double>*> arg(size); - - for (int iq = 0; iq < nPoints; iq++) { - for (int i = 0; i < size; i++) - arg[i] = &(gradsAtQPs[i][iq]); - - C[iq] += (*f)(vecAtQPs[iq], arg); - } - } - - void VecAndVecOfGradientsAtQP_ZOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - int size = static_cast<int>(vecs.size()); - std::vector<WorldVector<double>*> arg(size); - - for (int iq = 0; iq < nPoints; iq++) { - for (int i = 0; i < size; i++) - arg[i] = &(gradsAtQPs[i][iq]); - - result[iq] += fac * (*f)(vecAtQPs[iq], arg) * uhAtQP[iq]; - } - } - - void VecGrad_FOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs = getVectorAtQPs(vec1, elInfo, subAssembler, quad); - gradAtQPs = getGradientsAtQPs(vec2, elInfo, subAssembler, quad); - } - - void VecGrad_FOT::initElement(const ElInfo* smallElInfo, - const ElInfo* largeElInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs = getVectorAtQPs(vec1, smallElInfo, largeElInfo, subAssembler, quad); - gradAtQPs = getGradientsAtQPs(vec2, smallElInfo, largeElInfo, subAssembler, quad); - } - - void VecGrad_FOT::getLb(const ElInfo *elInfo, int nPoints, - VectorOfFixVecs<DimVec<double> >& Lb) const { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - lb(Lambda, (*vecFct)(vecAtQPs[iq], gradAtQPs[iq]), Lb[iq], 1.0); - } - - void VecGrad_FOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor) - { - if (grdUhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - WorldVector<double> b = (*vecFct)(vecAtQPs[iq], gradAtQPs[iq]); - result[iq] += b * grdUhAtQP[iq] * factor; - } - } - } - - void VecGrad_SOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - int dow = Global::getGeo(WORLD); - - if (D2UhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq]); - double resultQP = 0.0; - for (int i = 0; i < dow; i++) - resultQP += D2UhAtQP[iq][i][i]; - result[iq] += fac * resultQP * factor; - } - } - } - - void VecGrad_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - int nPoints = grdUhAtQP.size(); - for (int iq = 0; iq < nPoints; iq++) { - double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq]); - axpy(factor, grdUhAtQP[iq], result[iq]); - } - } - - void VecGrad_SOT::getLALt(const ElInfo *elInfo, int nPoints, - DimMat<double> **LALt) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - l1lt(Lambda, *(LALt[iq]), (*f)(vecAtQPs[iq], gradAtQPs[iq])); - } - - void VecGrad_SOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - vecAtQPs = subAssembler->getVectorAtQPs(vec1, elInfo, quad); - gradAtQPs = subAssembler->getGradientsAtQPs(vec2, elInfo, quad); - } - - void FctGrad2_FOT::initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad) - { - grad1AtQPs = subAssembler->getGradientsAtQPs(vec1, elInfo, quad); - grad2AtQPs = subAssembler->getGradientsAtQPs(vec2, elInfo, quad); - } - - void FctGrad2_FOT::getLb(const ElInfo *elInfo, int nPoints, - VectorOfFixVecs<DimVec<double> >& Lb) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - lb(Lambda, (*vecFct)(grad1AtQPs[iq], grad2AtQPs[iq]), Lb[iq], 1.0); - } - - void FctGrad2_FOT::eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor) - { - if (grdUhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - WorldVector<double> b = (*vecFct)(grad1AtQPs[iq], grad2AtQPs[iq]); - result[iq] += b * grdUhAtQP[iq] * factor; - } - } - } - } diff --git a/AMDiS/src/Operator.h b/AMDiS/src/Operator.h index 624c5a7d..bff990b6 100644 --- a/AMDiS/src/Operator.h +++ b/AMDiS/src/Operator.h @@ -31,3058 +31,13 @@ #include "AbstractFunction.h" #include "OpenMP.h" #include "SubAssembler.h" +#include "OperatorTerm.h" +#include "ZeroOrderTerm.h" +#include "FirstOrderTerm.h" +#include "SecondOrderTerm.h" namespace AMDiS { - /** - * \ingroup Assembler - * - * \brief - * Base class for ZeroOrderTerm, FirstOrderTerm and SecondOrderTerm. - * OperatorTerms are the building blocks of an Operator. Each OperatorTerm - * has its properties which are regarded, when constructing - * an Assembler for the corresponding Operator. - */ - class OperatorTerm - { - public: - /** \brief - * Constructs an OperatorTerm with initially no properties. - * degree_ is used to determine the degree of the needed quadrature - * for the assemblage. - */ - OperatorTerm(int deg) - : properties(0), - degree(deg), - dimOfWorld(Global::getGeo(WORLD)), - bOne(-1) - {} - - /// Destructor. - virtual ~OperatorTerm() {} - - /** \brief - * Virtual method. It's called by SubAssembler::initElement() for - * each OperatorTerm belonging to this SubAssembler. E.g., vectors - * and coordinates at quadrature points can be calculated here. - */ - virtual void initElement(const ElInfo*, SubAssembler*, Quadrature *quad = NULL) - {} - - virtual void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo, - SubAssembler*, Quadrature *quad = NULL) - {} - - - /// Returs \auxFeSpaces, the list of all aux fe spaces the operator makes use off. - inline std::set<const FiniteElemSpace*>& getAuxFeSpaces() - { - return auxFeSpaces; - } - - /// Specifies whether the matrix of the term is symmetric - void setSymmetric(bool symm); - - /// Returns true, if the term is piecewise constant, returns false otherwise - inline bool isPWConst() - { - return (degree == 0); - } - - /// Returns true, if the term has a symmetric matrix, returns false otherwise. - bool isSymmetric(); - - /// Returns \ref degree. - inline int getDegree() - { - return degree; - } - - /// Sets one component of the b vector to be one. See \ref bOne. - void setB(int b) - { - bOne = b; - } - - /// Evaluation of the OperatorTerm at all quadrature points. - virtual void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor) = 0; - - /** \brief - * Determines the value of a dof vector at the quadrature points of a given - * element. It is used by all VecAtQP like operator terms. - */ - double *getVectorAtQPs(DOFVectorBase<double>* vec, - const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad); - - /** \brief - * Determines the value of a dof vector at the quadrature points of a given - * element. This function is used, if an operator is assembled on two different - * meshes using the dual traverse. The element, i.e. the small or the large one, - * is choosen, which corresponds to the mesh the dof vector is defined on. - */ - double *getVectorAtQPs(DOFVectorBase<double>* vec, - const ElInfo* smallElInfo, - const ElInfo* largeElInfo, - SubAssembler* subAssembler, - Quadrature *quad); - - /// - WorldVector<double>* getGradientsAtQPs(DOFVectorBase<double>* vec, - const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad); - - /// - WorldVector<double>* getGradientsAtQPs(DOFVectorBase<double>* vec, - const ElInfo* smallElInfo, - const ElInfo* largeElInfo, - SubAssembler* subAssembler, - Quadrature *quad); - - protected: - /// Evaluation of \f$ \Lambda \cdot A \cdot \Lambda^t\f$. - void lalt(const DimVec<WorldVector<double> >& Lambda, - const WorldMatrix<double>& matrix, - DimMat<double>& LALt, - bool symm, - double factor) const; - - /** \brief - * Evaluation of \f$ \Lambda \cdot A \cdot \Lambda^t\f$ for \f$ A \f$ - * the matrix having a ONE in the position \f$ (K,L) \f$ - * and ZEROS in all other positions. - */ - static void lalt_kl(const DimVec<WorldVector<double> >& Lambda, - int k, int l, - DimMat<double>& LALt, - double factor); - - /// Evaluation of \f$ \Lambda \cdot A \cdot \Lambda^t\f$ for A equal to the identity. - inline void l1lt(const DimVec<WorldVector<double> >& Lambda, - DimMat<double>& LALt, - double factor) const - { - const int dim = LALt.getNumRows(); - - for (int i = 0; i < dim; i++) { - double val = 0.0; - for (int k = 0; k < dimOfWorld; k++) - val += Lambda[i][k] * Lambda[i][k]; - val *= factor; - LALt[i][i] += val; - for (int j = i + 1; j < dim; j++) { - val = 0.0; - for (int k = 0; k < dimOfWorld; k++) - val += Lambda[i][k] * Lambda[j][k]; - val *= factor; - LALt[i][j] += val; - LALt[j][i] += val; - } - } - } - - /// Evaluation of \f$ \Lambda \cdot b\f$. - inline void lb(const DimVec<WorldVector<double> >& Lambda, - const WorldVector<double>& b, - DimVec<double>& Lb, - double factor) const - { - const int dim = Lambda.getSize(); - - for (int i = 0; i < dim; i++) { - double val = 0.0; - - for (int j = 0; j < dimOfWorld; j++) - val += Lambda[i][j] * b[j]; - - Lb[i] += val * factor; - } - } - - /// Evaluation of \f$ \Lambda \cdot b\f$. - inline void lb_one(const DimVec<WorldVector<double> >& Lambda, - DimVec<double>& Lb, - double factor) const - { - const int dim = Lambda.getSize(); - - for (int i = 0; i < dim; i++) - Lb[i] += Lambda[i][bOne] * factor; - } - - /** \brief - * Evaluation of \f$ \Lambda \cdot b\f$ if b contains the value 1.0 in - * each component. - */ - inline void l1(const DimVec<WorldVector<double> >& Lambda, - DimVec<double>& Lb, - double factor) const - { - const int dim = Lambda.getSize(); - - for (int i = 0; i < dim; i++) { - double val = 0.0; - - for (int j = 0; j < dimOfWorld; j++) - val += Lambda[i][j]; - - Lb[i] += val * factor; - } - } - - protected: - /// Stores the properties of this OperatorTerm - Flag properties; - - /// Polynomial degree of the term. Used to detemine the degree of the quadrature. - int degree; - - /// Stores the dimension of the world. - int dimOfWorld; - - /// List off all fe spaces, the operator term makes use off. - std::set<const FiniteElemSpace*> auxFeSpaces; - - /// Pointer to the Operator this OperatorTerm belongs to. - Operator* operat; - - /** \brief - * In many cases, the vector b in the evaluation \f$ \Lambda \cdot b\f$ has zeros - * in all components expect one that is set to one. Using the function \ref lb is - * then unnecessary time consuming. Instead, this variable defines the component - * of the vector b to be one. The function \ref lb_one is used if this variable is - * not -1. - */ - int bOne; - - /// Flag for piecewise constant terms - static const Flag PW_CONST; - - /// Flag for symmetric terms - static const Flag SYMMETRIC; - - friend class SubAssembler; - friend class ZeroOrderAssembler; - friend class FirstOrderAssembler; - friend class SecondOrderAssembler; - friend class Operator; - }; - - /** - * \ingroup Assembler - * - * \brief - * Describes the second order terms: \f$ \nabla \cdot A \nabla u(\vec{x}) \f$ - */ - class SecondOrderTerm : public OperatorTerm - { - public: - /// Constructor. - SecondOrderTerm(int deg) - : OperatorTerm(deg) - {} - - /// Destructor. - virtual ~SecondOrderTerm() - {} - - /// Evaluation of \f$ \Lambda A \Lambda^t \f$ at all quadrature points. - virtual void getLALt(const ElInfo *elInfo, - int nPoints, - DimMat<double> **result) const = 0; - - /// Evaluation of \f$ A \nabla u(\vec{x}) \f$ at all quadrature points. - virtual void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) = 0; - - }; - - /** - * \ingroup Assembler - * - * \brief - * Implements the laplace operator: \f$ \Delta u(\vec{x}) \f$ - */ - class Laplace_SOT : public SecondOrderTerm - { - public: - /// Constructor. - Laplace_SOT() - : SecondOrderTerm(0) - { - setSymmetric(true); - } - - /// Implenetation of SecondOrderTerm::getLALt(). - inline void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - - for (int iq = 0; iq < nPoints; iq++) - l1lt(Lambda, *(LALt[iq]), 1.0); - } - - /// Implementation of SecondOrderTerm::eval(). - inline void eval(int nPoints, - const double *, - const WorldVector<double> *, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor) - { - int dow = Global::getGeo(WORLD); - - if (D2UhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - double resultQP = 0.0; - for (int i = 0; i < dow; i++) - resultQP += D2UhAtQP[iq][i][i]; - result[iq] += factor * resultQP; - } - } - } - - /// Implenetation of SecondOrderTerm::weakEval(). - void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - int nPoints = grdUhAtQP.size(); - for (int iq = 0; iq < nPoints; iq++) - result[iq] += grdUhAtQP[iq]; - } - }; - - /** - * \ingroup Assembler - * - * \brief - * Implements the laplace operator multiplied with a scalar factor: - * \f$ f \cdot \Delta u(\vec{x}) \f$ - */ - class FactorLaplace_SOT : public SecondOrderTerm - { - public: - /// Constructor. - FactorLaplace_SOT(double f) - : SecondOrderTerm(0) - { - factor = new double; - *factor = f; - - setSymmetric(true); - } - - /// Constructor. - FactorLaplace_SOT(double *fptr) - : SecondOrderTerm(0), - factor(fptr) - { - setSymmetric(true); - } - - /// Implements SecondOrderTerm::getLALt(). - inline void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - l1lt(Lambda, *(LALt[iq]), (*factor)); - } - - /// Implenetation of SecondOrderTerm::eval(). - void eval(int nPoints, - const double *, - const WorldVector<double> *, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double f) - { - int dow = Global::getGeo(WORLD); - - if (D2UhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - double resultQP = 0.0; - for (int i = 0; i < dow; i++) { - resultQP += D2UhAtQP[iq][i][i]; - } - result[iq] += resultQP * f * (*factor); - } - } - } - - /// Implenetation of SecondOrderTerm::weakEval(). - void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - int nPoints = grdUhAtQP.size(); - for (int iq = 0; iq < nPoints; iq++) - axpy(*factor, grdUhAtQP[iq], result[iq]); - } - - private: - /// Pointer to the factor. - double *factor; - }; - - /** - * \ingroup Assembler - * - * \brief - * SecondOrderTerm where A is a function which maps a DOFVector evaluated at - * a given quadrature point to a WolrdMatrix: - * \f$ \nabla \cdot A(v(\vec{x})) \nabla u(\vec{x}) \f$ - */ - class MatrixFct_SOT : public SecondOrderTerm - { - public: - /// Constructor. - MatrixFct_SOT(DOFVectorBase<double> *dv, - AbstractFunction<WorldMatrix<double>, double> *fct, - AbstractFunction<WorldVector<double>, WorldMatrix<double> > *div, - bool sym = false); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements SecondOrderTerm::getLALt(). - void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; - - /// Implenetation of SecondOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - /// Implenetation of 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>* vec; - - /// Pointer to the values of the DOFVector at quadrature points. - double* vecAtQPs; - - /// Function for A. - AbstractFunction<WorldMatrix<double>, double>* matrixFct; - - /// - AbstractFunction<WorldVector<double>, WorldMatrix<double> >* divFct; - - /// True, if \ref matrixFct produces always symmetric matrices. - bool symmetric; - }; - - /** - * \ingroup Assembler - * - * \brief - * SecondOrderTerm where A is a given fixed WorldMatrix<double>: - * \f$ \nabla \cdot A \nabla u(\vec{x}) \f$ - */ - class Matrix_SOT : public SecondOrderTerm { - public: - /// Constructor - Matrix_SOT(WorldMatrix<double> mat) - : SecondOrderTerm(0), matrix(mat) - { - symmetric = matrix.isSymmetric(); - setSymmetric(symmetric); - } - - /// Implements SecondOrderTerm::getLALt(). - inline void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const - { - const DimVec<WorldVector<double> >& Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - lalt(Lambda, matrix, *(LALt[iq]), symmetric, 1.0); - } - - /// Implenetation of SecondOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - /// Implenetation of SecondOrderTerm::weakEval(). - void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result); - - protected: - /// Matrix stroring A. - WorldMatrix<double> matrix; - - /// True, if \ref matrix is symmetric. - bool symmetric; - }; - - /** - * \ingroup Assembler - * - * \brief - * SecondOrderTerm where A is a WorldMatrix<double> having a ONE in position IJ - * and ZERO in all other positions - * \f$ \nabla \cdot A \nabla u(\vec{x}) \f$ - */ - class FactorIJ_SOT : public SecondOrderTerm - { - public: - /// Constructor. - FactorIJ_SOT(int x_i, int x_j, double f) - : SecondOrderTerm(0), xi(x_i), xj(x_j) - { - factor = new double; - *factor = f; - - setSymmetric(xi == xj); - } - - /// Constructor. - FactorIJ_SOT(int x_i, int x_j, double *fptr) - : SecondOrderTerm(0), xi(x_i), xj(x_j), factor(fptr) - { - setSymmetric(xi == xj); - } - - /// Implements SecondOrderTerm::getLALt(). - inline void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - for (int iq = 0; iq < nPoints; iq++) - lalt_kl(Lambda, xi, xj, *(LALt[iq]), (*factor)); - } - - /// Implenetation of SecondOrderTerm::eval(). - void eval(int nPoints, - const double *, - const WorldVector<double> *, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac) - { - if (D2UhAtQP) - for (int iq = 0; iq < nPoints; iq++) - result[iq] += (*factor) * D2UhAtQP[iq][xi][xj] * fac; - } - - /// Implenetation of SecondOrderTerm::weakEval(). - void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result) - { - int nPoints = grdUhAtQP.size(); - for (int iq = 0; iq < nPoints; iq++) - result[iq][xi] += (*factor) * grdUhAtQP[iq][xj]; - } - - private: - /// Directions for the derivatives. - int xi, xj; - - /// Pointer to the factor. - double *factor; - }; - - /** - * \ingroup Assembler - * - * \brief - * Laplace operator multiplied with a function evaluated at the quadrature - * points of a given DOFVector: - * \f$ f(v(\vec{x})) \Delta u(\vec{x}) \f$ - */ - class VecAtQP_SOT : public SecondOrderTerm { - public: - /// Constructor. - VecAtQP_SOT(DOFVectorBase<double> *dv, AbstractFunction<double, double> *af); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implementation of \ref OperatorTerm::initElement() for multilpe meshes. - void initElement(const ElInfo* smallElInfo, - const ElInfo* largeElInfo, - SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements SecondOrderTerm::getLALt(). - void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; - - /// Implenetation of SecondOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - /// Implenetation of 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>* vec; - - /// Pointer to an array containing the DOFVector evaluated at quadrature points. - double* vecAtQPs; - - /// Function evaluated at \ref vecAtQPs. - AbstractFunction<double, double> *f; - }; - - /** - * \ingroup Assembler - * - * \brief - * Laplace operator multiplied with a function evaluated at the quadrature - * points of a given DOFVector: - * \f$ f(v(\vec{x}), w(\vec{x})) \Delta u(\vec{x}) \f$ - */ - class Vec2AtQP_SOT : public SecondOrderTerm { - public: - /// Constructor. - Vec2AtQP_SOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, - BinaryAbstractFunction<double, double, double> *af); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements SecondOrderTerm::getLALt(). - void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; - - /// Implenetation of SecondOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - /// Implenetation of 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. - double* vecAtQPs1; - double* vecAtQPs2; - - /// Function evaluated at \ref vecAtQPs. - BinaryAbstractFunction<double, double, double> *f; - }; - - /** - * \ingroup Assembler - * - * \brief - * Laplace multiplied with a function evaluated at each quadrature point: - * \f$ f(\vec{x}) \Delta u(\vec{x}) \f$ - */ - class CoordsAtQP_SOT : public SecondOrderTerm { - public: - /// Constructor. - CoordsAtQP_SOT(AbstractFunction<double, WorldVector<double> > *af) - : SecondOrderTerm(af->getDegree()), g(af) - { - setSymmetric(true); - } - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements SecondOrderTerm::getLALt(). - void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; - - /// Implenetation of SecondOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - /// Implenetation of SecondOrderTerm::weakEval(). - void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result); - - - protected: - /// Stores coordinates at quadrature points. Set in \ref initElement(). - WorldVector<double>* coordsAtQPs; - - /// Function evaluated at quadrature points. - AbstractFunction<double, WorldVector<double> > *g; - }; - - /** - * \ingroup Assembler - * - * \brief - * SecondOrderTerm where A is a function which maps the gradient of a - * DOFVector at each quadrature point to WorldMatrix<double>: - * \f$ \nabla \cdot A(\nabla v(\vec{x})) \nabla u(\vec{x})\f$ - */ - class MatrixGradient_SOT : public SecondOrderTerm - { - public: - /// Constructor. - MatrixGradient_SOT(DOFVectorBase<double> *dv, - AbstractFunction<WorldMatrix<double>, WorldVector<double> > *af, - AbstractFunction<WorldVector<double>, WorldMatrix<double> > *divAf, - bool symm = false); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implementation of \ref OperatorTerm::initElement() for multilpe meshes. - void initElement(const ElInfo* smallElInfo, - const ElInfo* largeElInfo, - SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements SecondOrderTerm::getLALt(). - void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; - - /// Implenetation of SecondOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - /// Implenetation of SecondOrderTerm::weakEval(). - void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result); - - protected: - DOFVectorBase<double>* vec; - - /// Function which maps each entry in \ref gradAtQPs to a WorldMatrix<double>. - AbstractFunction<WorldMatrix<double>, WorldVector<double> > *f; - - AbstractFunction<WorldVector<double>, WorldMatrix<double> > *divFct; - - /** \brief - * Pointer to a WorldVector<double> array containing the gradients of the DOFVector - * at each quadrature point. - */ - WorldVector<double>* gradAtQPs; - - /// True, if \ref f provides always a symmetric WorldMatrix<double>. - bool symmetric; - - private: - /// Temporary matrix used in \ref MatrixGradient_SOT::weakEval. - WorldMatrix<double> tmpMat; - }; - - /** - * \ingroup Assembler - * - * \brief - * Laplace multiplied with a function which maps the gradient of a DOFVector - * at each quadrature point to a double: - * \f$ f(\nabla v(\vec{x})) \Delta u(\vec{x}) \f$ - */ - class FctGradient_SOT : public SecondOrderTerm - { - public: - /// Constructor. - FctGradient_SOT(DOFVectorBase<double> *dv, - AbstractFunction<double, WorldVector<double> > *af); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements SecondOrderTerm::getLALt(). - void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; - - /// Implenetation of SecondOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - /// Implenetation of SecondOrderTerm::weakEval(). - void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result); - - protected: - DOFVectorBase<double>* vec; - - /// Function wich maps \ref gradAtQPs to a double. - AbstractFunction<double, WorldVector<double> > *f; - - /** \brief - * Pointer to a WorldVector<double> array containing the gradients of the DOFVector - * at each quadrature point. - */ - WorldVector<double>* gradAtQPs; - }; - - - /** - * \ingroup Assembler - * - * \brief - * Laplace multiplied with a function which maps the gradient of a DOFVector - * at each quadrature point to a double: - * \f$ \nabla \cdot A(v(\vec{x}), \nabla v(\vec{x})) \nabla u(\vec{x}) \f$ - */ - class VecMatrixGradientAtQP_SOT : public SecondOrderTerm - { - public: - /// Constructor. - VecMatrixGradientAtQP_SOT(DOFVectorBase<double> *dv, - BinaryAbstractFunction<WorldMatrix<double>, double, WorldVector<double> > *af, - AbstractFunction<WorldVector<double>, WorldMatrix<double> > *divAf, - bool symm = false); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements SecondOrderTerm::getLALt(). - void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; - - /// Implenetation of SecondOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - /// Implenetation of SecondOrderTerm::weakEval(). - void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result); - - protected: - DOFVectorBase<double>* vec; - - /// Function wich maps \ref gradAtQPs to a double. - BinaryAbstractFunction<WorldMatrix<double>, - double, WorldVector<double> > *f; - - AbstractFunction<WorldVector<double>, WorldMatrix<double> > *divFct; - - /** \brief - * Pointer to a WorldVector<double> array containing the gradients of the DOFVector - * at each quadrature point. - */ - double* vecAtQPs; - WorldVector<double>* gradAtQPs; - - bool symmetric; - }; - - /** - * \ingroup Assembler - * - * \brief - * Laplace multiplied with a function which maps the gradient of a DOFVector - * at each quadrature point to a double: - * \f$ f(\nabla v(\vec{x})) \Delta u(\vec{x}) \f$ - */ - class VecGradCoordsAtQP_SOT : public SecondOrderTerm - { - public: - /// Constructor. - VecGradCoordsAtQP_SOT(DOFVectorBase<double> *dv, - TertiaryAbstractFunction<double, double, - WorldVector<double>, WorldVector<double> > *af); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements SecondOrderTerm::getLALt(). - void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; - - /// Implenetation of SecondOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - /// Implenetation of SecondOrderTerm::weakEval(). - void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result); - - protected: - DOFVectorBase<double>* vec; - - /// Function wich maps \ref gradAtQPs to a double. - TertiaryAbstractFunction<double, double, WorldVector<double>, - WorldVector<double> > *f; - - /** \brief - * Pointer to a WorldVector<double> array containing the gradients of the DOFVector - * at each quadrature point. - */ - double* vecAtQPs; - WorldVector<double>* gradAtQPs; - WorldVector<double>* coordsAtQPs; - - }; - - - /** - * \ingroup Assembler - * - * \brief - * Laplace operator multiplied with a function evaluated at the quadrature - * points of a given DOFVector: - * \f$ -f(v(\vec{x})) \Delta u(\vec{x}) \f$ - */ - class VecAndCoordsAtQP_SOT : public SecondOrderTerm { - public: - /// Constructor. - VecAndCoordsAtQP_SOT(DOFVectorBase<double> *dv, - BinaryAbstractFunction<double, double, WorldVector<double> > *af); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements SecondOrderTerm::eval(). - void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; - - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result); - - protected: - /// DOFVector to be evaluated at quadrature points. - DOFVectorBase<double>* vec; - - /// Pointer to an array containing the DOFVector evaluated at quadrature points. - double* vecAtQPs; - - WorldVector<double>* coordsAtQPs; - - /// Function evaluated at \ref vecAtQPs. - BinaryAbstractFunction<double, double, WorldVector<double> > *f; - }; - - /** - * \ingroup Assembler - * - * \brief - * SecondOrderTerm where A is a function which maps the gradient of a - * DOFVector at each quadrature point to WorldMatrix<double>: - * \f$ \nabla \cdot A(\nabla v(\vec{x})) \nabla u(\vec{x})\f$ - */ - class MatrixGradientAndCoords_SOT : public SecondOrderTerm - { - public: - /// Constructor. - MatrixGradientAndCoords_SOT(DOFVectorBase<double> *dv, - BinaryAbstractFunction<WorldMatrix<double>, - WorldVector<double> , - WorldVector<double> > *af, - AbstractFunction<WorldVector<double>, - WorldMatrix<double> > *divAf, - bool symm = false); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements SecondOrderTerm::getLALt(). - void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; - - /// Implenetation of SecondOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - /// Implenetation of SecondOrderTerm::weakEval(). - void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result); - - protected: - DOFVectorBase<double>* vec; - - /// Function which maps each entry in \ref gradAtQPs to a WorldMatrix<double>. - BinaryAbstractFunction<WorldMatrix<double>, - WorldVector<double>, WorldVector<double> > *f; - - AbstractFunction<WorldVector<double>, WorldMatrix<double> > *divFct; - - /** \brief - * Pointer to a WorldVector<double> array containing the gradients of the DOFVector - * at each quadrature point. - */ - WorldVector<double>* gradAtQPs; - - WorldVector<double>* coordsAtQPs; - - /// True, if \ref f provides always a symmetric WorldMatrix<double>. - bool symmetric; - }; - - class MatrixVec2_SOT : public SecondOrderTerm - { - public: - /// Constructor. - MatrixVec2_SOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, - BinaryAbstractFunction<double, double, double> *f, - WorldMatrix<double> Af, - bool sym = false); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements SecondOrderTerm::getLALt(). - void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; - - /// Implenetation of SecondOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - /// Implenetation of 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 the values of the DOFVector at quadrature points. - double* vec1AtQPs; - double* vec2AtQPs; - - /// Function for A. - BinaryAbstractFunction<double, double, double> * fct; - - /// - WorldMatrix<double> A; - - /// True, if \ref matrixFct produces always symmetric matrices. - bool symmetric; - }; - - - class General_SOT : public SecondOrderTerm - { - public: - /// Constructor. - General_SOT(std::vector<DOFVectorBase<double>*> vecs, - std::vector<DOFVectorBase<double>*> grads, - TertiaryAbstractFunction<WorldMatrix<double>, - WorldVector<double>, - std::vector<double>, - std::vector<WorldVector<double> > > *f, - AbstractFunction<WorldVector<double>, - WorldMatrix<double> > *divFct, - bool symmetric); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo*, SubAssembler*, Quadrature *quad= NULL); - - /// Implements SecondOrderTerm::getLALt(). - void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; - - /// Implenetation of SecondOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - /// Implenetation of SecondOrderTerm::weakEval(). - void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result); - - protected: - std::vector<DOFVectorBase<double>*> vecs_; - - std::vector<DOFVectorBase<double>*> grads_; - - TertiaryAbstractFunction<WorldMatrix<double>, - WorldVector<double>, - std::vector<double>, - std::vector<WorldVector<double> > > *f_; - - AbstractFunction<WorldVector<double>, - WorldMatrix<double> > *divFct_; - - WorldVector<double> *coordsAtQPs_; - - std::vector<double*> vecsAtQPs_; - - std::vector<WorldVector<double>*> gradsAtQPs_; - - bool symmetric_; - }; - - class GeneralParametric_SOT : public SecondOrderTerm - { - public: - /// Constructor. - GeneralParametric_SOT(std::vector<DOFVectorBase<double>*> vecs, - std::vector<DOFVectorBase<double>*> grads, - QuartAbstractFunction<WorldMatrix<double>, - WorldVector<double>, - WorldVector<double>, - std::vector<double>, - std::vector<WorldVector<double> > > *f, - AbstractFunction<WorldVector<double>, - WorldMatrix<double> > *divFct, - bool symmetric); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo*, - SubAssembler* , - Quadrature *quad= NULL); - - /// Implements SecondOrderTerm::getLALt(). - void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; - - /// Implenetation of SecondOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - /// Implenetation of SecondOrderTerm::weakEval(). - void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result); - - protected: - std::vector<DOFVectorBase<double>*> vecs_; - - std::vector<DOFVectorBase<double>*> grads_; - - QuartAbstractFunction<WorldMatrix<double>, - WorldVector<double>, - WorldVector<double>, - std::vector<double>, - std::vector<WorldVector<double> > > *f_; - - AbstractFunction<WorldVector<double>, - WorldMatrix<double> > *divFct_; - - WorldVector<double> *coordsAtQPs_; - WorldVector<double> elementNormal_; - - std::vector<double*> vecsAtQPs_; - - std::vector<WorldVector<double>*> gradsAtQPs_; - - bool symmetric_; - }; - - - // ============================================================================ - // ===== class FirstOrderTerm ================================================= - // ============================================================================ - - /** - * \ingroup Assembler - * - * \brief - * Describes the first order terms: \f$ b \cdot \nabla u(\vec{x}) \f$ - */ - class FirstOrderTerm : public OperatorTerm - { - public: - /// Constructor. - FirstOrderTerm(int deg) - : OperatorTerm(deg) - {} - - /// Destructor. - virtual ~FirstOrderTerm() {} - - /// Evaluation of \f$ \Lambda b \f$. - virtual void getLb(const ElInfo *elInfo, - int nPoints, - VectorOfFixVecs<DimVec<double> >& result) const = 0; - - /// Implenetation of FirstOrderTerm::eval(). - void eval(int nPoints, - const double *, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *, - double *result, - double factor) - { - int dow = Global::getGeo(WORLD); - - if (grdUhAtQP) { - for (int iq = 0; iq < nPoints; iq++) { - double resultQP = 0.0; - for (int i = 0; i < dow; i++) - resultQP += grdUhAtQP[iq][i]; - - result[iq] += resultQP * factor; - } - } - } - - }; - - /** - * \ingroup Assembler - * - * \brief - * First order term: \f$ b \cdot \nabla u(\vec{x}) \f$ with a vector b which - * only consits of entries equal to one. - */ - class Simple_FOT : public FirstOrderTerm - { - public: - /// Constructor. - Simple_FOT() - : FirstOrderTerm(0) - {} - - /// Implements FirstOrderTerm::getLb(). - inline void getLb(const ElInfo *elInfo, - int nPoints, - VectorOfFixVecs<DimVec<double> >& Lb) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - - for (int iq = 0; iq < nPoints; iq++) - l1(Lambda, Lb[iq], 1.0); - } - }; - - /** - * \ingroup Assembler - * - * \brief - * First order term: \f$ b \cdot \nabla u(\vec{x}) \f$ with a vector b which - * only consits of entries equal to one. - */ - class FactorSimple_FOT : public FirstOrderTerm - { - public: - /// Constructor. - FactorSimple_FOT(double f) - : FirstOrderTerm(0) - { - factor = new double; - *factor = f; - } - - /// Constructor. - FactorSimple_FOT(double *fptr) - : FirstOrderTerm(0), factor(fptr) - {} - - /// Implements FirstOrderTerm::getLb(). - inline void getLb(const ElInfo *elInfo, int nPoints, VectorOfFixVecs<DimVec<double> >& Lb) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - - for (int iq = 0; iq < nPoints; iq++) - l1(Lambda, Lb[iq], (*factor)); - } - - private: - /// Pointer to the factor. - double *factor; - }; - - /** - * \ingroup Assembler - * - * \brief - * First order term: \f$ b \cdot \nabla u(\vec{x}) \f$ with a given vector b. - */ - class Vector_FOT : public FirstOrderTerm - { - public: - /// Constructor. - Vector_FOT(WorldVector<double> wv) - : FirstOrderTerm(0), b(wv) - {} - - /// Constructor. - Vector_FOT(int bIdx) - : FirstOrderTerm(0) - { - bOne = bIdx; - } - - /// Implements FirstOrderTerm::getLb(). - inline void getLb(const ElInfo *elInfo, - int nPoints, - VectorOfFixVecs<DimVec<double> >&Lb) const - { - const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); - - if (bOne > -1) { - for (int iq = 0; iq < nPoints; iq++) - lb_one(Lambda, Lb[iq], 1.0); - } else { - for (int iq = 0; iq < nPoints; iq++) - lb(Lambda, b, Lb[iq], 1.0); - } - } - - /// Implements FirstOrderTerm::eval(). - void eval(int nPoints, - const double *, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *, - double *result, - double factor) - { - if (grdUhAtQP) - for (int iq = 0; iq < nPoints; iq++) - result[iq] += b * grdUhAtQP[iq] * factor; - } - - protected: - /// Vector which is multiplied with \f$ \nabla u(\vec{x}) \f$ - WorldVector<double> b; - }; - - /** - * \ingroup Assembler - * - * \brief - * Simple_FOT multiplied with \f$ f(v(\vec{x})) \f$. - */ - class VecAtQP_FOT : public FirstOrderTerm - { - public: - /// Constructor. - VecAtQP_FOT(DOFVectorBase<double> *dv, - AbstractFunction<double, double> *af, - WorldVector<double> *wv); - - /// Constructor. - VecAtQP_FOT(DOFVectorBase<double> *dv, - AbstractFunction<double, double> *af, - int bIdx); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements FirstOrderTerm::getLb(). - void getLb(const ElInfo *elInfo, int nPoints, - VectorOfFixVecs<DimVec<double> >& Lb) const; - - /// Implements FirstOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - protected: - /// DOFVector to be evaluated at quadrature points. - DOFVectorBase<double>* vec; - - /// v at quadrature points. - double *vecAtQPs; - - /// Function f. - AbstractFunction<double, double> *f; - - /// - WorldVector<double> *b; - }; - - /** - * \ingroup Assembler - * - * \brief - * Simple_FOT multiplied with \f$ f(\vec{x}) \f$. - */ - class CoordsAtQP_FOT : public FirstOrderTerm - { - public: - /// Constructor. - CoordsAtQP_FOT(AbstractFunction<double, WorldVector<double> > *af) - : FirstOrderTerm(af->getDegree()), g(af) - {} - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements FistOrderTerm::getLb(). - void getLb(const ElInfo *elInfo, int nPoints,VectorOfFixVecs<DimVec<double> >&Lb) const; - - /// Implements FirstOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - protected: - /// Stores coordinates at quadrature points. Set in \ref initElement(). - WorldVector<double>* coordsAtQPs; - - /// Function avaluated at world coordinates. - AbstractFunction<double, WorldVector<double> > *g; - }; - - /** - * \ingroup Assembler - * - * \brief - * Vector_FOT multiplied with \f$ f(\vec{x}) \f$. - */ - class VecCoordsAtQP_FOT : public FirstOrderTerm - { - public: - /// Constructor. - VecCoordsAtQP_FOT(AbstractFunction<double, WorldVector<double> > *af, - WorldVector<double> wv) - : FirstOrderTerm(af->getDegree()), g(af), b(wv) - {} - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements FistOrderTerm::getLb(). - void getLb(const ElInfo *elInfo, int nPoints, - VectorOfFixVecs<DimVec<double> >& Lb) const; - - /// Implements FirstOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - protected: - /// Stores coordinates at quadrature points. Set in \ref initElement(). - WorldVector<double>* coordsAtQPs; - - /// Function evaluated at world coordinates. - AbstractFunction<double, WorldVector<double> > *g; - - /// Coefficient vector. - WorldVector<double> b; - }; - - /** - * \ingroup Assembler - * - * \brief - * First order term: \f$ b(\nabla v(\vec{x})) \cdot \nabla u(\vec{x})\f$. - */ - class VectorGradient_FOT : public FirstOrderTerm - { - public: - /// Constructor. - VectorGradient_FOT(DOFVectorBase<double> *dv, - AbstractFunction<WorldVector<double>, WorldVector<double> > *af); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements FirstOrderTerm::getLb(). - void getLb(const ElInfo *elInfo, int nPoints, - VectorOfFixVecs<DimVec<double> >& Lb) const; - - /// Implements FirstOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - protected: - DOFVectorBase<double>* vec; - - /// Function for b. - AbstractFunction<WorldVector<double>, WorldVector<double> > *f; - - /// Gradient of v at quadrature points. - WorldVector<double> *gradAtQPs; - }; - - /** - * \ingroup Assembler - * - * \brief - * First order term: \f$ b(v(\vec{x})) \cdot \nabla u(\vec{x})\f$. - */ - class VectorFct_FOT : public FirstOrderTerm - { - public: - /// Constructor. - VectorFct_FOT(DOFVectorBase<double> *dv, - AbstractFunction<WorldVector<double>, double> *fct); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements FirstOrderTerm::getLb(). - void getLb(const ElInfo *elInfo, int qPoint, - VectorOfFixVecs<DimVec<double> >& Lb) const; - - /// Implements FirstOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - protected: - /// DOFVector to be evaluated at quadrature points. - DOFVectorBase<double>* vec; - - /// Vector v at quadrature points. - double *vecAtQPs; - - /// Function for b. - AbstractFunction<WorldVector<double>, double> *vecFct; - }; - - /** - * \ingroup Assembler - * - * \brief - * - */ - class VecFctAtQP_FOT : public FirstOrderTerm - { - public: - /// Constructor. - VecFctAtQP_FOT(AbstractFunction<WorldVector<double>, WorldVector<double> > *af) - : FirstOrderTerm(af->getDegree()), g(af) - {} - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements FistOrderTerm::getLb(). - void getLb(const ElInfo *elInfo, int nPoints, - VectorOfFixVecs<DimVec<double> >&Lb) const; - - /// Implements FirstOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - protected: - /// Stores coordinates at quadrature points. Set in \ref initElement(). - WorldVector<double>* coordsAtQPs; - - /// Function avaluated at world coordinates. - AbstractFunction<WorldVector<double>, WorldVector<double> > *g; - }; - - - /** - * \ingroup Assembler - * - * \brief - * First order term: \f$ b(v(\vec{x}), \nabla w(\vec{x})) \cdot \nabla u(\vec{x})\f$. - */ - class VecGrad_FOT : public FirstOrderTerm - { - public: - /// Constructor. - VecGrad_FOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, - BinaryAbstractFunction<WorldVector<double>, double, WorldVector<double> > *fct); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implementation of \ref OperatorTerm::initElement() for multilpe meshes. - void initElement(const ElInfo* smallElInfo, - const ElInfo* largeElInfo, - SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements FirstOrderTerm::getLb(). - void getLb(const ElInfo *elInfo, int qPoint, - VectorOfFixVecs<DimVec<double> >& Lb) const; - - /// Implements FirstOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - protected: - /// DOFVector to be evaluated at quadrature points. - DOFVectorBase<double>* vec1; - DOFVectorBase<double>* vec2; - - /// Vector v at quadrature points. - double *vecAtQPs; - - WorldVector<double> *gradAtQPs; - - /// Function for b. - BinaryAbstractFunction<WorldVector<double>, double, WorldVector<double> > *vecFct; - }; - - - /** - * \ingroup Assembler - * - * \brief - * First order term: \f$ b(\nabla v(\vec{x}), \nabla w(\vec{x})) \cdot \nabla u(\vec{x})\f$. - */ - class FctGrad2_FOT : public FirstOrderTerm - { - public: - /// Constructor - FctGrad2_FOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, - BinaryAbstractFunction<WorldVector<double>, WorldVector<double>, WorldVector<double> > *vecFct_) - : FirstOrderTerm(vecFct_->getDegree()), vec1(dv1), vec2(dv2), vecFct(vecFct_) - {} - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements FirstOrderTerm::getLb(). - void getLb(const ElInfo *elInfo, int qPoint, - VectorOfFixVecs<DimVec<double> >& Lb) const; - - /// Implements FirstOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - protected: - /// DOFVector to be evaluated at quadrature points. - DOFVectorBase<double>* vec1; - - /// DOFVector to be evaluated at quadrature points. - DOFVectorBase<double>* vec2; - - /// Gradient v at quadrature points. - WorldVector<double> *grad1AtQPs; - - /// Gradient v at quadrature points. - WorldVector<double> *grad2AtQPs; - - /// Function for b. - BinaryAbstractFunction<WorldVector<double>, WorldVector<double>, WorldVector<double> > *vecFct; - }; - - - class Vec2AndGradAtQP_FOT : public FirstOrderTerm - { - public: - Vec2AndGradAtQP_FOT(DOFVectorBase<double> *dv1, - DOFVectorBase<double> *dv2, - TertiaryAbstractFunction<double, double, double, WorldVector<double> > *f_, WorldVector<double> *b_); - - void initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad = NULL); - - void getLb(const ElInfo *elInfo, - int nPoints, - VectorOfFixVecs<DimVec<double> >& Lb) const; - - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - protected: - DOFVectorBase<double>* vec1; - DOFVectorBase<double>* vec2; - - double *vec1AtQPs; - double *vec2AtQPs; - WorldVector<double> *gradAtQPs1; - - TertiaryAbstractFunction<double, double, double, WorldVector<double> > *f; - WorldVector<double> *b; - }; - - - class FctVecAtQP_FOT : public FirstOrderTerm - { - public: - FctVecAtQP_FOT(DOFVectorBase<double> *dv, - BinaryAbstractFunction<double, WorldVector<double>, double> *f_, - WorldVector<double> *b_); - - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - void getLb(const ElInfo *elInfo, int nPoints, - VectorOfFixVecs<DimVec<double> >& Lb) const; - - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - protected: - DOFVectorBase<double>* vec; - double *vecAtQPs; - WorldVector<double> *coordsAtQPs; - BinaryAbstractFunction<double, WorldVector<double>, double> *f; - WorldVector<double> *b; - }; - - - class Vec2AtQP_FOT : public FirstOrderTerm - { - public: - Vec2AtQP_FOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, - BinaryAbstractFunction<double, double, double> *af, - WorldVector<double> *b_); - - Vec2AtQP_FOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, - BinaryAbstractFunction<double, double, double> *af, - int bIdx); - - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - void getLb(const ElInfo *elInfo, int nPoints, - VectorOfFixVecs<DimVec<double> >& Lb) const; - - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - protected: - DOFVectorBase<double>* vec1; - DOFVectorBase<double>* vec2; - double *vec1AtQPs; - double *vec2AtQPs; - /// Function f. - BinaryAbstractFunction<double, double, double> *f; - WorldVector<double> *b; - }; - - - class Vec3FctAtQP_FOT : public FirstOrderTerm - { - public: - Vec3FctAtQP_FOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, DOFVectorBase<double> *dv3, - TertiaryAbstractFunction<double, double, double, double> *f, - WorldVector<double> *b); - - Vec3FctAtQP_FOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, DOFVectorBase<double> *dv3, - TertiaryAbstractFunction<double, double, double, double> *f, - int b); - - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - void getLb(const ElInfo *elInfo, int nPoints, - VectorOfFixVecs<DimVec<double> >& Lb) const; - - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - protected: - DOFVectorBase<double>* vec1; - DOFVectorBase<double>* vec2; - DOFVectorBase<double>* vec3; - TertiaryAbstractFunction<double, double, double, double>* f; - double *vec1AtQPs; - double *vec2AtQPs; - double *vec3AtQPs; - WorldVector<double> *b; - }; - - - class General_FOT : public FirstOrderTerm - { - public: - /// Constructor - General_FOT(std::vector<DOFVectorBase<double>*> vecs, - std::vector<DOFVectorBase<double>*> grads, - TertiaryAbstractFunction<WorldVector<double>, - WorldVector<double>, - std::vector<double>, - std::vector<WorldVector<double> > > *f); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo*, - SubAssembler* , - Quadrature *quad= NULL); - - /// Implements FirstOrderTerm::getLb(). - void getLb(const ElInfo *elInfo, int nPoints, - VectorOfFixVecs<DimVec<double> >& result) const; - - /// Implenetation of FirstOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - protected: - std::vector<DOFVectorBase<double>*> vecs_; - - std::vector<DOFVectorBase<double>*> grads_; - - TertiaryAbstractFunction<WorldVector<double>, - WorldVector<double>, - std::vector<double>, - std::vector<WorldVector<double> > > *f_; - - WorldVector<double> *coordsAtQPs_; - - std::vector<double*> vecsAtQPs_; - - std::vector<WorldVector<double>*> gradsAtQPs_; - }; - - class GeneralParametric_FOT : public FirstOrderTerm - { - public: - /// Constructor - GeneralParametric_FOT(std::vector<DOFVectorBase<double>*> vecs, - std::vector<DOFVectorBase<double>*> grads, - QuartAbstractFunction<WorldVector<double>, - WorldVector<double>, - WorldVector<double>, - std::vector<double>, - std::vector<WorldVector<double> > > *f); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo*, SubAssembler*, Quadrature *quad = NULL); - - /// Implements FirstOrderTerm::getLb(). - void getLb(const ElInfo *elInfo, int nPoints, - VectorOfFixVecs<DimVec<double> >& result) const; - - /// Implenetation of FirstOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - protected: - std::vector<DOFVectorBase<double>*> vecs_; - - std::vector<DOFVectorBase<double>*> grads_; - - QuartAbstractFunction<WorldVector<double>, - WorldVector<double>, - WorldVector<double>, - std::vector<double>, - std::vector<WorldVector<double> > > *f_; - - WorldVector<double> *coordsAtQPs_; - WorldVector<double> elementNormal_; - - std::vector<double*> vecsAtQPs_; - - std::vector<WorldVector<double>*> gradsAtQPs_; - }; - - - // ============================================================================ - // ===== class ZeroOrderTerm ================================================== - // ============================================================================ - - /** - * \ingroup Assembler - * - * \brief - * Describes zero order terms: \f$ cu(\vec{x}) \f$. - */ - class ZeroOrderTerm : public OperatorTerm - { - public: - /// Constructor. - ZeroOrderTerm(int deg) : OperatorTerm(deg) {} - - /// Destructor. - virtual ~ZeroOrderTerm() {} - - /// Evaluates \f$ c \f$ - virtual void getC(const ElInfo *elInfo, int nPoints, - std::vector<double> &C) = 0; - - }; - - /** - * \ingroup Assembler - * - * \brief - * Simple zero order term - */ - class Simple_ZOT : public ZeroOrderTerm - { - public: - /// Constructor. - Simple_ZOT(double f = 1.0) : ZeroOrderTerm(0), factor(f) {} - - /// Implements ZeroOrderTerm::getC(). - inline void getC(const ElInfo *, int nPoints, std::vector<double> &C) - { - for (int iq = 0; iq < nPoints; iq++) - C[iq] += factor; - } - - /// Implements ZeroOrderTerm::eval(). - inline void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *, - const WorldMatrix<double> *, - double *result, - double fac) - { - for (int iq = 0; iq < nPoints; iq++) - result[iq] += fac * factor * uhAtQP[iq]; - } - - protected: - /// Constant factor of zero order term. - double factor; - }; - - /** - * \ingroup Assembler - * - * \brief - * Zero order term: \f$ f(v(\vec{x})) u(\vec{x})\f$ - */ - class VecAtQP_ZOT : public ZeroOrderTerm - { - public: - /// Constructor. - VecAtQP_ZOT(DOFVectorBase<double> *dv, - AbstractFunction<double, double> *ab); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implementation of \ref OperatorTerm::initElement() for multilpe meshes. - void initElement(const ElInfo* smallElInfo, - const ElInfo* largeElInfo, - SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements ZeroOrderTerm::getC(). - void getC(const ElInfo *, int nPoints, std::vector<double> &C); - - /// Implements ZeroOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - /// DOFVector to be evaluated at quadrature points. - DOFVectorBase<double>* vec; - - /// Vector v at quadrature points. - double *vecAtQPs; - - /// Function for c. - AbstractFunction<double, double> *f; - }; - - /** - * \ingroup Assembler - * - * \brief - * Zero order term: \f$ f(v(\vec{x})) g(w(\vec{x})) u(\vec{x})\f$ - */ - class MultVecAtQP_ZOT : public ZeroOrderTerm - { - public: - /// Constructor. - MultVecAtQP_ZOT(DOFVectorBase<double> *dv1, - DOFVectorBase<double> *dv2, - AbstractFunction<double, double> *f1, - AbstractFunction<double, double> *f2); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements ZeroOrderTerm::getC(). - void getC(const ElInfo *, int nPoints, std::vector<double> &C); - - /// Implements ZeroOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - /// DOFVectorBase to be evaluated at quadrature points. - DOFVectorBase<double>* vec1; - DOFVectorBase<double>* vec2; - - /// Vector v at quadrature points. - double *vecAtQPs1; - double *vecAtQPs2; - - /// Function for c. - AbstractFunction<double, double> *f1; - AbstractFunction<double, double> *f2; - }; - - /** - * \ingroup Assembler - * - * \brief - * Zero order term: \f$ f(v(\vec{x}), w(\vec{x})) u(\vec{x})\f$ - */ - class Vec2AtQP_ZOT : public ZeroOrderTerm - { - public: - /// Constructor. - Vec2AtQP_ZOT(DOFVectorBase<double> *dv1, - DOFVectorBase<double> *dv2, - BinaryAbstractFunction<double, double, double> *f); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implementation of \ref OperatorTerm::initElement() for multilpe meshes. - void initElement(const ElInfo* smallElInfo, - const ElInfo* largeElInfo, - SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements ZeroOrderTerm::getC(). - void getC(const ElInfo *, int nPoints, std::vector<double> &C); - - /// Implements ZeroOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - /// First DOFVector to be evaluated at quadrature points. - DOFVectorBase<double>* vec1; - /// Second DOFVector to be evaluated at quadrature points. - DOFVectorBase<double>* vec2; - - /// Values of the first DOFVector at the quadrature points. - double *vecAtQPs1; - /// Values of the second DOFVector at the quadrature points. - double *vecAtQPs2; - - /// Function for c. - BinaryAbstractFunction<double, double, double> *f; - }; - - - /** - * \ingroup Assembler - * - * \brief - * Zero order term: \f$ f(v(\vec{x}), w(\vec{x})) u(\vec{x})\f$ - */ - class Vec3AtQP_ZOT : public ZeroOrderTerm - { - public: - /// Constructor. - Vec3AtQP_ZOT(DOFVectorBase<double> *dv1, - DOFVectorBase<double> *dv2, - DOFVectorBase<double> *dv3, - TertiaryAbstractFunction<double, double, double, double> *f); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements ZeroOrderTerm::getC(). - void getC(const ElInfo *, int nPoints, std::vector<double> &C); - - /// Implements ZeroOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - /// DOFVectors to be evaluated at quadrature points. - DOFVectorBase<double> *vec1, *vec2, *vec3; - - /// Vectors at quadrature points. - double *vecAtQPs1, *vecAtQPs2, *vecAtQPs3; - - /// Function for c. - TertiaryAbstractFunction<double, double, double, double> *f; - }; - - - /** - * \ingroup Assembler - * - * \brief - * - */ - class FctGradientCoords_ZOT : public ZeroOrderTerm - { - public: - /// Constructor. - FctGradientCoords_ZOT(DOFVectorBase<double> *dv, - BinaryAbstractFunction<double, WorldVector<double>, WorldVector<double> > *f); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements SecondOrderTerm::getC(). - void getC(const ElInfo *elInfo, int nPoints, std::vector<double> &C); - - /// Implements ZeroOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - DOFVectorBase<double>* vec; - - /// Function wich maps \ref gradAtQPs to a double. - BinaryAbstractFunction<double, WorldVector<double>, WorldVector<double> > *f; - - /** \brief - * Pointer to a WorldVector<double> array containing the gradients of the DOFVector - * at each quadrature point. - */ - WorldVector<double>* gradAtQPs; - - WorldVector<double>* coordsAtQPs; - - }; - - /** - * \ingroup Assembler - * - * \brief - */ - class VecGradCoordsAtQP_ZOT : public ZeroOrderTerm - { - public: - /// Constructor. - VecGradCoordsAtQP_ZOT(DOFVectorBase<double> *dv, - TertiaryAbstractFunction<double, double, WorldVector<double>, WorldVector<double> > *f); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements ZeroOrderTerm::getC(). - void getC(const ElInfo *, int nPoints, std::vector<double> &C); - - /// Implements ZeroOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - /// DOFVector to be evaluated at quadrature points. - DOFVectorBase<double>* vec; - - /// Vector v at quadrature points. - double *vecAtQPs; - - /// Gradient at quadrature points. - WorldVector<double>* gradAtQPs; - - WorldVector<double>* coordsAtQPs; - - /// Function for c. - TertiaryAbstractFunction<double, double, WorldVector<double>, WorldVector<double> > *f; - }; - - /** - * \ingroup Assembler - * - * \brief - */ - class VecAndCoordsAtQP_ZOT : public ZeroOrderTerm - { - public: - /// Constructor. - VecAndCoordsAtQP_ZOT(DOFVectorBase<double> *dv, - BinaryAbstractFunction<double, double, WorldVector<double> > *f); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements ZeroOrderTerm::getC(). - void getC(const ElInfo *, int nPoints, std::vector<double> &C); - - /// Implements ZeroOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - /// DOFVector to be evaluated at quadrature points. - DOFVectorBase<double>* vec; - - /// Vector v at quadrature points. - double *vecAtQPs; - - /// Gradient at quadrature points. - WorldVector<double>* coordsAtQPs; - - /// Function for c. - BinaryAbstractFunction<double, double, WorldVector<double> > *f; - }; - - - /** - * \ingroup Assembler - * - * \brief - */ - class Vec2AndGradAtQP_ZOT : public ZeroOrderTerm - { - public: - /// Constructor. - Vec2AndGradAtQP_ZOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, - TertiaryAbstractFunction<double, double, WorldVector<double>, double > *af); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements ZeroOrderTerm::getC(). - void getC(const ElInfo *, int nPoints, std::vector<double> &C); - - /// Implements ZeroOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - /// DOFVector to be evaluated at quadrature points. - DOFVectorBase<double>* vec1; - DOFVectorBase<double>* vec2; - - /// Vector v at quadrature points. - double *vecAtQPs1; - double *vecAtQPs2; - - /// Gradient at quadrature points. - WorldVector<double> *gradAtQPs; - - /// Function for c. - TertiaryAbstractFunction<double, double, WorldVector<double>, double > *f; - }; - - - /** - * \ingroup Assembler - * - * \brief - * - */ - class FctGradient_ZOT : public ZeroOrderTerm - { - public: - /// Constructor. - FctGradient_ZOT(DOFVectorBase<double> *dv, - AbstractFunction<double, WorldVector<double> > *f); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements SecondOrderTerm::getC(). - void getC(const ElInfo *elInfo, int nPoints, std::vector<double> &C); - - /// Implements ZeroOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - DOFVectorBase<double>* vec; - - /// Function wich maps \ref gradAtQPs to a double. - AbstractFunction<double, WorldVector<double> > *f; - - /** \brief - * Pointer to a WorldVector<double> array containing the gradients of the DOFVector - * at each quadrature point. - */ - WorldVector<double>* gradAtQPs; - - }; - - /** - * \ingroup Assembler - * - * \brief - */ - class VecAndGradAtQP_ZOT : public ZeroOrderTerm - { - public: - /// Constructor. - VecAndGradAtQP_ZOT(DOFVectorBase<double> *dv, - BinaryAbstractFunction<double, double, WorldVector<double> > *f); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements ZeroOrderTerm::getC(). - void getC(const ElInfo *, int nPoints, std::vector<double> &C); - - /// Implements ZeroOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - /// DOFVector to be evaluated at quadrature points. - DOFVectorBase<double>* vec; - - /// Vector v at quadrature points. - double *vecAtQPs; - - /// Gradient at quadrature points. - WorldVector<double> *gradAtQPs; - - /// Function for c. - BinaryAbstractFunction<double, double, WorldVector<double> > *f; - }; - - /** - * \ingroup Assembler - * - * \brief - * Laplace multiplied with a function which maps the gradient of a DOFVector - * at each quadrature point to a double: - * \f$ f(\nabla v(\vec{x})) \Delta u(\vec{x}) \f$ - */ - class VecAndGradAtQP_SOT : public SecondOrderTerm - { - public: - /// Constructor. - VecAndGradAtQP_SOT(DOFVectorBase<double> *dv, - BinaryAbstractFunction<double, double, WorldVector<double> > *af); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - - /// Implements SecondOrderTerm::getLALt(). - void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; - - /// Implements SecondOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - 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>* vec; - - /// Vector v at quadrature points. - double *vecAtQPs; - - /// Gradient at quadrature points. - WorldVector<double> *gradAtQPs; - - /// Function for c. - BinaryAbstractFunction<double, double, WorldVector<double> > *f; - }; - - - /** - * \ingroup Assembler - * - * \brief - * Second order term: \f$ f(v(\vec{x}),\nabla w(\vec{x})) \Delta u(\vec{x})\f$ - */ - class VecGrad_SOT : public SecondOrderTerm - { - public: - /// Constructor. - VecGrad_SOT( DOFVectorBase<double> *dv1, - DOFVectorBase<double> *dv2, - BinaryAbstractFunction<double, double, WorldVector<double> > *f_) - : SecondOrderTerm(f_->getDegree()), vec1(dv1), vec2(dv2), f(f_) - {} - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements SecondOrderTerm::getLALt(). - inline void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; - - /// Implements SecondOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - /// Implements SecondOrderTerm::weakEval(). - void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result); - - protected: - /// DOFVectors to be evaluated at quadrature points. - DOFVectorBase<double>* vec1; - DOFVectorBase<double>* vec2; - - /// Vector v at quadrature points. - double *vecAtQPs; - - /// Gradient at quadrature points. - WorldVector<double> *gradAtQPs; - - /// Function for c. - BinaryAbstractFunction<double, double, WorldVector<double> > *f; - }; - - - /* - * \ingroup Assembler - * - * \brief - * Zero order term: \f$ f(\vec{x}) u(\vec{x})\f$ - */ - class CoordsAtQP_ZOT : public ZeroOrderTerm - { - public: - /// Constructor. - CoordsAtQP_ZOT(AbstractFunction<double, WorldVector<double> > *af) - : ZeroOrderTerm(af->getDegree()), g(af) - {} - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, - SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements ZeroOrderTerm::getC(). - void getC(const ElInfo *, int nPoints, std::vector<double> &C); - - /// Implements ZeroOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - /// Stores coordinates at quadrature points. Set in \ref initElement(). - WorldVector<double>* coordsAtQPs; - - /// Function for c. - AbstractFunction<double, WorldVector<double> > *g; - }; - - /** - * \ingroup Assembler - * - * \brief - * SecondOrderTerm where A(x) is a WorldMatrix having a in all positions - * except possibly the position IJ - * \f$ \nabla \cdot A(x) \nabla u(\vec{x}) \f$ - */ - class CoordsAtQP_IJ_SOT : public SecondOrderTerm - { - public: - /// Constructor. - CoordsAtQP_IJ_SOT(AbstractFunction<double, WorldVector<double> > *af, - int x_i, int x_j) - : SecondOrderTerm(af->getDegree()), g(af), xi(x_i), xj(x_j) - { - setSymmetric(xi == xj); - } - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements SecondOrderTerm::getLALt(). - inline void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; - - /// Implements SecondOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double factor); - - /// Implements SecondOrderTerm::weakEval(). - void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, - std::vector<WorldVector<double> > &result); - - private: - /// Stores coordinates at quadrature points. Set in \ref initElement(). - WorldVector<double>* coordsAtQPs; - - /// Function evaluated at quadrature points. - AbstractFunction<double, WorldVector<double> > *g; - - /// Directions for the derivatives. - 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 a given DOFVector: - * \f$ \nabla \cdot f(v(\vec{x})) A \nabla u(\vec{x}) \f$ - */ - class VecAtQP_IJ_SOT : public SecondOrderTerm - { - public: - /// Constructor. - VecAtQP_IJ_SOT(DOFVectorBase<double> *dv, AbstractFunction<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, int nPoints, DimMat<double> **LALt) const; - - /// Implements SecondOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - 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>* vec; - - /// Pointer to an array containing the DOFVector evaluated at quadrature points. - double* vecAtQPs; - - /// Function evaluated at \ref vecAtQPs. - AbstractFunction<double, double> *f; - - private: - /// Directions for the derivatives. - int xi, xj; - }; - - class VecAndGradVecAtQP_ZOT : public ZeroOrderTerm - { - public: - /// Constructor. - VecAndGradVecAtQP_ZOT(DOFVectorBase<double> *dv, - DOFVectorBase<double> *dGrd, - BinaryAbstractFunction<double, double, WorldVector<double> > *f); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements ZeroOrderTerm::getC(). - void getC(const ElInfo *, int nPoints, std::vector<double> &C); - - /// Implements ZeroOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - /// DOFVector to be evaluated at quadrature points. - DOFVectorBase<double>* vec; - - /// Vector v at quadrature points. - double *vecAtQPs; - - /// First DOFVector whose gradient is evaluated at quadrature points. - DOFVectorBase<double>* vecGrd; - - /// Gradient of first vector at quadrature points. - WorldVector<double> *gradAtQPs; - - /// Function for c. - BinaryAbstractFunction<double, double, WorldVector<double> > *f; - }; - - class VecAndGradVec2AtQP_ZOT : public ZeroOrderTerm - { - public: - /// Constructor. - VecAndGradVec2AtQP_ZOT(DOFVectorBase<double> *dv, - DOFVectorBase<double> *dGrd1, - DOFVectorBase<double> *dGrd2, - TertiaryAbstractFunction<double, double, WorldVector<double>, WorldVector<double> > *af); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements ZeroOrderTerm::getC(). - void getC(const ElInfo *, int nPoints, std::vector<double> &C); - - /// Implements ZeroOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - /// DOFVector to be evaluated at quadrature points. - DOFVectorBase<double>* vec; - - /// Vector v at quadrature points. - double *vecAtQPs; - - /// First DOFVector whose gradient is evaluated at quadrature points. - DOFVectorBase<double>* vecGrd1; - - /// Gradient of first vector at quadrature points. - WorldVector<double> *grad1AtQPs; - - /// Second DOFVector whose gradient is evaluated at quadrature points. - DOFVectorBase<double>* vecGrd2; - - /// Gradient of second vector at quadrature points. - WorldVector<double> *grad2AtQPs; - - /// Function for c. - TertiaryAbstractFunction<double, double, WorldVector<double>, WorldVector<double> > *f; - }; - - - class VecOfDOFVecsAtQP_ZOT : public ZeroOrderTerm - { - public: - /// Constructor. - VecOfDOFVecsAtQP_ZOT(const std::vector<DOFVectorBase<double>*>& dv, - AbstractFunction<double, std::vector<double> > *f); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements ZeroOrderTerm::getC(). - void getC(const ElInfo *, int nPoints, std::vector<double> &C); - - /// Implements ZeroOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - /// Vector of DOFVectors to be evaluated at quadrature points. - std::vector<DOFVectorBase<double>*> vecs; - - /// Vectors at quadrature points. - std::vector<double*> vecsAtQPs; - - /// Function for c. - AbstractFunction<double, std::vector<double> > *f; - }; - - class VecOfGradientsAtQP_ZOT : public ZeroOrderTerm - { - public: - /// Constructor. - VecOfGradientsAtQP_ZOT(const std::vector<DOFVectorBase<double>*>& dv, - AbstractFunction<double, std::vector<WorldVector<double>*> > *af); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements ZeroOrderTerm::getC(). - void getC(const ElInfo *, int nPoints, std::vector<double> &C); - - /// Implements ZeroOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - /// Vector of DOFVectors to be evaluated at quadrature points. - std::vector<DOFVectorBase<double>*> vecs; - - /// Vectors at quadrature points. - std::vector<WorldVector<double>*> gradsAtQPs; - - /// Function for c. - AbstractFunction<double, std::vector<WorldVector<double>*> > *f; - }; - - - class VecDivergence_ZOT : public ZeroOrderTerm - { - public: - /// Constructor. - VecDivergence_ZOT(int nComponents, - DOFVectorBase<double> *vec0, - DOFVectorBase<double> *vec1 = NULL, - DOFVectorBase<double> *vec2 = NULL); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements ZeroOrderTerm::getC(). - void getC(const ElInfo *, int nPoints, std::vector<double> &C); - - /// Implements ZeroOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - /// Vector of DOFVectors to be evaluated at quadrature points. - std::vector<DOFVectorBase<double>*> vecs; - - /// Vectors at quadrature points. - std::vector<WorldVector<double>*> gradsAtQPs; - }; - - - - class VecAndVecOfGradientsAtQP_ZOT : public ZeroOrderTerm - { - public: - /// Constructor. - VecAndVecOfGradientsAtQP_ZOT(DOFVector<double> *v, - const std::vector<DOFVector<double>*>& dv, - BinaryAbstractFunction<double, double, std::vector<WorldVector<double>*> > *af); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements ZeroOrderTerm::getC(). - void getC(const ElInfo *, int nPoints, std::vector<double> &C); - - /// Implements ZeroOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - /// DOFVector to be evaluated at quadrature points. - DOFVector<double>* vec; - - /// Vector v at quadrature points. - double *vecAtQPs; - - /// Vector of DOFVectors to be evaluated at quadrature points. - std::vector<DOFVector<double>*> vecs; - - /// Vectors at quadrature points. - std::vector<WorldVector<double>*> gradsAtQPs; - - /// Function for c. - BinaryAbstractFunction<double, double, std::vector<WorldVector<double>*> > *f; - }; - - - class Vec2AndGrad2AtQP_ZOT : public ZeroOrderTerm - { - public: - Vec2AndGrad2AtQP_ZOT(DOFVectorBase<double> *dv1, - DOFVectorBase<double> *dv2, - QuartAbstractFunction<double, double, double, WorldVector<double>, WorldVector<double> > *af); - - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - void getC(const ElInfo *, int nPoints, std::vector<double> &C); - - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - DOFVectorBase<double> *vec1, *vec2; - - double *vecAtQPs1, *vecAtQPs2; - - WorldVector<double> *gradAtQPs1, *gradAtQPs2; - - QuartAbstractFunction<double, double, double, WorldVector<double>,WorldVector<double> > *f; - }; - - - class Vec2AndGradVecAtQP_ZOT : public ZeroOrderTerm - { - public: - Vec2AndGradVecAtQP_ZOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, - DOFVectorBase<double> *dGrd, - TertiaryAbstractFunction<double, double, double, WorldVector<double> > *f); - - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - void getC(const ElInfo *, int nPoints, std::vector<double> &C); - - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - DOFVectorBase<double>* vec1; - DOFVectorBase<double>* vec2; - - double *vec1AtQPs; - double *vec2AtQPs; - - DOFVectorBase<double>* vecGrd; - WorldVector<double> *gradAtQPs; - - TertiaryAbstractFunction<double, double, double, WorldVector<double> > *f; - }; - - - - class General_ZOT : public ZeroOrderTerm - { - public: - /// Constructor. - General_ZOT(std::vector<DOFVectorBase<double>*> vecs, - std::vector<DOFVectorBase<double>*> grads, - TertiaryAbstractFunction<double, WorldVector<double>, std::vector<double>, std::vector<WorldVector<double> > > *f); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements ZeroOrderTerm::getC(). - void getC(const ElInfo *, int nPoints, std::vector<double> &C); - - /// Implements ZeroOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - std::vector<DOFVectorBase<double>*> vecs_; - - std::vector<DOFVectorBase<double>*> grads_; - - TertiaryAbstractFunction<double, - WorldVector<double>, - std::vector<double>, - std::vector<WorldVector<double> > > *f_; - - WorldVector<double> *coordsAtQPs_; - - std::vector<double*> vecsAtQPs_; - - std::vector<WorldVector<double>*> gradsAtQPs_; - - std::vector<double> vecsArg; - - std::vector<WorldVector<double> > gradsArg; - }; - - class GeneralParametric_ZOT : public ZeroOrderTerm - { - public: - /// Constructor. - GeneralParametric_ZOT(std::vector<DOFVectorBase<double>*> vecs, - std::vector<DOFVectorBase<double>*> grads, - QuartAbstractFunction<double, - WorldVector<double>, - WorldVector<double>, - std::vector<double>, - std::vector<WorldVector<double> > > *f); - - /// Implementation of \ref OperatorTerm::initElement(). - void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, - Quadrature *quad = NULL); - - /// Implements ZeroOrderTerm::getC(). - void getC(const ElInfo *, int nPoints, std::vector<double> &C); - - /// Implements ZeroOrderTerm::eval(). - void eval(int nPoints, - const double *uhAtQP, - const WorldVector<double> *grdUhAtQP, - const WorldMatrix<double> *D2UhAtQP, - double *result, - double fac); - - protected: - std::vector<DOFVectorBase<double>*> vecs_; - - std::vector<DOFVectorBase<double>*> grads_; - - QuartAbstractFunction<double, - WorldVector<double>, - WorldVector<double>, - std::vector<double>, - std::vector<WorldVector<double> > > *f_; - - WorldVector<double> *coordsAtQPs_; - - WorldVector<double> elementNormal_; - - std::vector<double*> vecsAtQPs_; - - std::vector<WorldVector<double>*> gradsAtQPs_; - }; - - /** \brief * An Operator holds all information needed to assemble the system matrix * and the right hand side. It consists of four OperatorTerm lists each storing diff --git a/AMDiS/src/OperatorTerm.cc b/AMDiS/src/OperatorTerm.cc new file mode 100644 index 00000000..946f7cb8 --- /dev/null +++ b/AMDiS/src/OperatorTerm.cc @@ -0,0 +1,183 @@ +#include "OperatorTerm.h" +#include "ElInfo.h" +#include "DOFVector.h" + +namespace AMDiS { + + const Flag OperatorTerm::PW_CONST = 1; + const Flag OperatorTerm::SYMMETRIC = 2; + + + void OperatorTerm::setSymmetric(bool symm) + { + if (symm) + properties.setFlag(SYMMETRIC); + else + properties.unsetFlag(SYMMETRIC); + } + + + bool OperatorTerm::isSymmetric() + { + return properties.isSet(SYMMETRIC); + } + + + double *OperatorTerm::getVectorAtQPs(DOFVectorBase<double>* vec, + const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + FUNCNAME("OperatorTerm::getVectorAtQPs()"); + + TEST_EXIT_DBG(elInfo->getMesh() == vec->getFESpace()->getMesh()) + ("There is something wrong!\n"); + + return subAssembler->getVectorAtQPs(vec, elInfo, quad); + } + + + double *OperatorTerm::getVectorAtQPs(DOFVectorBase<double>* vec, + const ElInfo* smallElInfo, + const ElInfo* largeElInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + FUNCNAME("OperatorTerm::getVectorAtQPs()"); + + TEST_EXIT(smallElInfo->getMesh() == vec->getFESpace()->getMesh() || + largeElInfo->getMesh() == vec->getFESpace()->getMesh()) + ("There is something wrong!\n"); + + if (smallElInfo->getLevel() == largeElInfo->getLevel()) { + + // Both elements have the same size, so we can use the simple procedure + // to determine the vecAtQPs. + + if (vec->getFESpace()->getMesh() == smallElInfo->getMesh()) + return subAssembler->getVectorAtQPs(vec, smallElInfo, quad); + else + return subAssembler->getVectorAtQPs(vec, largeElInfo, quad); + + } else { + + // The two elements are different. If the vector is defined on the mesh of the + // small element, we can still use the simple procedure to determine the vecAtQPs. + + if (vec->getFESpace()->getMesh() == largeElInfo->getMesh()) + return subAssembler->getVectorAtQPs(vec, smallElInfo, largeElInfo, quad); + else + return subAssembler->getVectorAtQPs(vec, smallElInfo, quad); + } + } + + + WorldVector<double>* OperatorTerm::getGradientsAtQPs(DOFVectorBase<double>* vec, + const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + FUNCNAME("OperatorTerm::getGradientsAtQPs()"); + + TEST_EXIT_DBG(elInfo->getMesh() == vec->getFESpace()->getMesh()) + ("There is something wrong!\n"); + + return subAssembler->getGradientsAtQPs(vec, elInfo, quad); + } + + + WorldVector<double>* OperatorTerm::getGradientsAtQPs(DOFVectorBase<double>* vec, + const ElInfo* smallElInfo, + const ElInfo* largeElInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + FUNCNAME("OperatorTerm::getGradientsAtQPs()"); + + ERROR_EXIT("Not yet tested!\n"); + + TEST_EXIT(smallElInfo->getMesh() == vec->getFESpace()->getMesh() || + largeElInfo->getMesh() == vec->getFESpace()->getMesh()) + ("There is something wrong!\n"); + + if (smallElInfo->getLevel() == largeElInfo->getLevel()) { + + // Both elements have the same size, so we can use the simple procedure + // to determine the gradients. + + if (vec->getFESpace()->getMesh() == smallElInfo->getMesh()) + return subAssembler->getGradientsAtQPs(vec, smallElInfo, quad); + else + return subAssembler->getGradientsAtQPs(vec, largeElInfo, quad); + + } else { + + // The two elements are different. If the vector is defined on the mesh of the + // small element, we can still use the simple procedure to determine the gradients. + + if (vec->getFESpace()->getMesh() == largeElInfo->getMesh()) + return subAssembler->getGradientsAtQPs(vec, smallElInfo, largeElInfo, quad); + else + return subAssembler->getGradientsAtQPs(vec, smallElInfo, quad); + } + } + + + void OperatorTerm::lalt(const DimVec<WorldVector<double> >& Lambda, + const WorldMatrix<double>& matrix, + DimMat<double>& LALt, + bool symm, + double factor) const + { + int j, k, l; + const int dimOfWorld = Global::getGeo(WORLD); + int dim = LALt.getNumRows() - 1; + + double val = 0.0; + + if (symm) { + for (int i = 0; i <= dim; i++) { + val = 0.0; + for (k = 0; k < dimOfWorld; k++) + for (l = 0; l < dimOfWorld; l++) + val += Lambda[i][k] * matrix[k][l] * Lambda[i][l]; + val *= factor; + LALt[i][i] += val; + for (j = i + 1; j <= dim; j++) { + val = 0.0; + for (k = 0; k < dimOfWorld; k++) + for (l = 0; l < dimOfWorld; l++) + val += Lambda[i][k] * matrix[k][l] * Lambda[j][l]; + val *= factor; + LALt[i][j] += val; + LALt[j][i] += val; + } + } + } else { + for (int i = 0; i <= dim; i++) { + for (j = 0; j <= dim; j++) { + val = 0.0; + for (k = 0; k < dimOfWorld; k++) + for (l = 0; l < dimOfWorld; l++) + val += Lambda[i][k] * matrix[k][l] * Lambda[j][l]; + val *= factor; + LALt[i][j] += val; + } + } + } + } + + + void OperatorTerm::lalt_kl(const DimVec<WorldVector<double> >& Lambda, + int k, int l, + DimMat<double>& LALt, + double factor) + { + int dim = LALt.getNumRows() - 1; + + for (int i = 0; i <= dim; i++) + for (int j = 0; j <= dim; j++) + LALt[i][j] += factor * Lambda[i][k] * Lambda[j][l]; + } + +} diff --git a/AMDiS/src/OperatorTerm.h b/AMDiS/src/OperatorTerm.h new file mode 100644 index 00000000..471e353c --- /dev/null +++ b/AMDiS/src/OperatorTerm.h @@ -0,0 +1,274 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == TU Dresden == +// == == +// == Institut f�r Wissenschaftliches Rechnen == +// == Zellescher Weg 12-14 == +// == 01069 Dresden == +// == germany == +// == == +// ============================================================================ +// == == +// == https://gforge.zih.tu-dresden.de/projects/amdis/ == +// == == +// ============================================================================ + +/** \file OperatorTerm.h */ + +#ifndef AMDIS_OPERATORTERM_H +#define AMDIS_OPERATORTERM_H + +#include <set> +#include "AMDiS_fwd.h" +#include "SubAssembler.h" + +namespace AMDiS { + + /** + * \ingroup Assembler + * + * \brief + * Base class for ZeroOrderTerm, FirstOrderTerm and SecondOrderTerm. + * OperatorTerms are the building blocks of an Operator. Each OperatorTerm + * has its properties which are regarded, when constructing + * an Assembler for the corresponding Operator. + */ + class OperatorTerm + { + public: + /** \brief + * Constructs an OperatorTerm with initially no properties. + * degree_ is used to determine the degree of the needed quadrature + * for the assemblage. + */ + OperatorTerm(int deg) + : properties(0), + degree(deg), + dimOfWorld(Global::getGeo(WORLD)), + bOne(-1) + {} + + /// Destructor. + virtual ~OperatorTerm() {} + + /** \brief + * Virtual method. It's called by SubAssembler::initElement() for + * each OperatorTerm belonging to this SubAssembler. E.g., vectors + * and coordinates at quadrature points can be calculated here. + */ + virtual void initElement(const ElInfo*, SubAssembler*, Quadrature *quad = NULL) + {} + + virtual void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo, + SubAssembler*, Quadrature *quad = NULL) + {} + + + /// Returs \auxFeSpaces, the list of all aux fe spaces the operator makes use off. + inline std::set<const FiniteElemSpace*>& getAuxFeSpaces() + { + return auxFeSpaces; + } + + /// Specifies whether the matrix of the term is symmetric + void setSymmetric(bool symm); + + /// Returns true, if the term is piecewise constant, returns false otherwise + inline bool isPWConst() + { + return (degree == 0); + } + + /// Returns true, if the term has a symmetric matrix, returns false otherwise. + bool isSymmetric(); + + /// Returns \ref degree. + inline int getDegree() + { + return degree; + } + + /// Sets one component of the b vector to be one. See \ref bOne. + void setB(int b) + { + bOne = b; + } + + /// Evaluation of the OperatorTerm at all quadrature points. + virtual void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) = 0; + + /** \brief + * Determines the value of a dof vector at the quadrature points of a given + * element. It is used by all VecAtQP like operator terms. + */ + double *getVectorAtQPs(DOFVectorBase<double>* vec, + const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad); + + /** \brief + * Determines the value of a dof vector at the quadrature points of a given + * element. This function is used, if an operator is assembled on two different + * meshes using the dual traverse. The element, i.e. the small or the large one, + * is choosen, which corresponds to the mesh the dof vector is defined on. + */ + double *getVectorAtQPs(DOFVectorBase<double>* vec, + const ElInfo* smallElInfo, + const ElInfo* largeElInfo, + SubAssembler* subAssembler, + Quadrature *quad); + + /// + WorldVector<double>* getGradientsAtQPs(DOFVectorBase<double>* vec, + const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad); + + /// + WorldVector<double>* getGradientsAtQPs(DOFVectorBase<double>* vec, + const ElInfo* smallElInfo, + const ElInfo* largeElInfo, + SubAssembler* subAssembler, + Quadrature *quad); + + protected: + /// Evaluation of \f$ \Lambda \cdot A \cdot \Lambda^t\f$. + void lalt(const DimVec<WorldVector<double> >& Lambda, + const WorldMatrix<double>& matrix, + DimMat<double>& LALt, + bool symm, + double factor) const; + + /** \brief + * Evaluation of \f$ \Lambda \cdot A \cdot \Lambda^t\f$ for \f$ A \f$ + * the matrix having a ONE in the position \f$ (K,L) \f$ + * and ZEROS in all other positions. + */ + static void lalt_kl(const DimVec<WorldVector<double> >& Lambda, + int k, int l, + DimMat<double>& LALt, + double factor); + + /// Evaluation of \f$ \Lambda \cdot A \cdot \Lambda^t\f$ for A equal to the identity. + inline void l1lt(const DimVec<WorldVector<double> >& Lambda, + DimMat<double>& LALt, + double factor) const + { + const int dim = LALt.getNumRows(); + + for (int i = 0; i < dim; i++) { + double val = 0.0; + for (int k = 0; k < dimOfWorld; k++) + val += Lambda[i][k] * Lambda[i][k]; + val *= factor; + LALt[i][i] += val; + for (int j = i + 1; j < dim; j++) { + val = 0.0; + for (int k = 0; k < dimOfWorld; k++) + val += Lambda[i][k] * Lambda[j][k]; + val *= factor; + LALt[i][j] += val; + LALt[j][i] += val; + } + } + } + + /// Evaluation of \f$ \Lambda \cdot b\f$. + inline void lb(const DimVec<WorldVector<double> >& Lambda, + const WorldVector<double>& b, + DimVec<double>& Lb, + double factor) const + { + const int dim = Lambda.getSize(); + + for (int i = 0; i < dim; i++) { + double val = 0.0; + + for (int j = 0; j < dimOfWorld; j++) + val += Lambda[i][j] * b[j]; + + Lb[i] += val * factor; + } + } + + /// Evaluation of \f$ \Lambda \cdot b\f$. + inline void lb_one(const DimVec<WorldVector<double> >& Lambda, + DimVec<double>& Lb, + double factor) const + { + const int dim = Lambda.getSize(); + + for (int i = 0; i < dim; i++) + Lb[i] += Lambda[i][bOne] * factor; + } + + /** \brief + * Evaluation of \f$ \Lambda \cdot b\f$ if b contains the value 1.0 in + * each component. + */ + inline void l1(const DimVec<WorldVector<double> >& Lambda, + DimVec<double>& Lb, + double factor) const + { + const int dim = Lambda.getSize(); + + for (int i = 0; i < dim; i++) { + double val = 0.0; + + for (int j = 0; j < dimOfWorld; j++) + val += Lambda[i][j]; + + Lb[i] += val * factor; + } + } + + protected: + /// Stores the properties of this OperatorTerm + Flag properties; + + /// Polynomial degree of the term. Used to detemine the degree of the quadrature. + int degree; + + /// Stores the dimension of the world. + int dimOfWorld; + + /// List off all fe spaces, the operator term makes use off. + std::set<const FiniteElemSpace*> auxFeSpaces; + + /// Pointer to the Operator this OperatorTerm belongs to. + Operator* operat; + + /** \brief + * In many cases, the vector b in the evaluation \f$ \Lambda \cdot b\f$ has zeros + * in all components expect one that is set to one. Using the function \ref lb is + * then unnecessary time consuming. Instead, this variable defines the component + * of the vector b to be one. The function \ref lb_one is used if this variable is + * not -1. + */ + int bOne; + + /// Flag for piecewise constant terms + static const Flag PW_CONST; + + /// Flag for symmetric terms + static const Flag SYMMETRIC; + + friend class SubAssembler; + friend class ZeroOrderAssembler; + friend class FirstOrderAssembler; + friend class SecondOrderAssembler; + friend class Operator; + }; + +} + +#endif diff --git a/AMDiS/src/SecondOrderTerm.cc b/AMDiS/src/SecondOrderTerm.cc new file mode 100644 index 00000000..b04af74c --- /dev/null +++ b/AMDiS/src/SecondOrderTerm.cc @@ -0,0 +1,1235 @@ +#include "SecondOrderTerm.h" +#include "DOFVector.h" + +namespace AMDiS { + + // ========== MatrixFct_SOT ========== + + MatrixFct_SOT::MatrixFct_SOT(DOFVectorBase<double> *dv, + AbstractFunction<WorldMatrix<double>, double> *fct, + AbstractFunction<WorldVector<double>, WorldMatrix<double> > *div, + bool sym) + : SecondOrderTerm(fct->getDegree()), + vec(dv), + matrixFct(fct), + divFct(div), + symmetric(sym) + { + setSymmetric(symmetric); + + TEST_EXIT(dv)("No vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + } + + void MatrixFct_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); + } + + void MatrixFct_SOT::getLALt(const ElInfo *elInfo, int nPoints, + DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + lalt(Lambda, (*matrixFct)(vecAtQPs[iq]), *(LALt[iq]), symmetric, 1.0); + } + + void MatrixFct_SOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) + { + int dow = Global::getGeo(WORLD); + + for (int iq = 0; iq < nPoints; iq++) { + double resultQP = 0.0; + + WorldMatrix<double> A = (*matrixFct)(vecAtQPs[iq]); + + if (D2UhAtQP) + for (int i = 0; i < dow; i++) + for (int j = 0; j < dow; j++) + resultQP += A[i][j] * D2UhAtQP[iq][j][i]; + + if (grdUhAtQP) + resultQP += (*divFct)(A) * grdUhAtQP[iq]; + + result[iq] += resultQP * factor; + } + } + + void MatrixFct_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + WorldMatrix<double> A; + for (int iq = 0; iq < nPoints; iq++) { + A = (*matrixFct)(vecAtQPs[iq]); + result[iq] += A * grdUhAtQP[iq]; + } + } + + + // ========== Matrix_SOT ========== + + void Matrix_SOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) + { + int dow = Global::getGeo(WORLD); + + if (D2UhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + double resultQP = 0.0; + for (int i = 0; i < dow; i++) + for (int j = 0; j < dow; j++) + resultQP += matrix[i][j] * D2UhAtQP[iq][j][i]; + + result[iq] += resultQP * factor; + } + } + } + + void Matrix_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + for (int iq = 0; iq < nPoints; iq++) + result[iq] += matrix * grdUhAtQP[iq]; + } + + + // ========== VecAtQP_SOT ========== + + VecAtQP_SOT::VecAtQP_SOT(DOFVectorBase<double> *dv, + AbstractFunction<double, double> *af) + : SecondOrderTerm(af->getDegree()), vec(dv), f(af) + { + setSymmetric(true); + + TEST_EXIT(dv)("No vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + } + + void VecAtQP_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature* quad) + { + vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); + } + + void VecAtQP_SOT::initElement(const ElInfo* smallElInfo, + const ElInfo* largeElInfo, + SubAssembler* subAssembler, + Quadrature* quad) + { + vecAtQPs = getVectorAtQPs(vec, smallElInfo, largeElInfo, subAssembler, quad); + } + + void VecAtQP_SOT::getLALt(const ElInfo *elInfo, int nPoints, + DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + l1lt(Lambda, *(LALt[iq]), (*f)(vecAtQPs[iq])); + } + + void VecAtQP_SOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + int dow = Global::getGeo(WORLD); + + if (D2UhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*f)(vecAtQPs[iq]); + double resultQP = 0.0; + for (int i = 0; i < dow; i++) + resultQP += D2UhAtQP[iq][i][i]; + result[iq] += fac * factor * resultQP; + } + } + } + + void VecAtQP_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*f)(vecAtQPs[iq]); + axpy(factor, grdUhAtQP[iq], result[iq]); + } + } + + + // ========== Vec2AtQP_SOT ========== + + Vec2AtQP_SOT::Vec2AtQP_SOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, + BinaryAbstractFunction<double, double, double> *af) + : SecondOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), f(af) + { + setSymmetric(true); + + TEST_EXIT(dv1)("No first vector!\n"); + TEST_EXIT(dv2)("No second vector!\n"); + + auxFeSpaces.insert(dv1->getFESpace()); + auxFeSpaces.insert(dv2->getFESpace()); + } + + void Vec2AtQP_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs1 = getVectorAtQPs(vec1, elInfo, subAssembler, quad); + vecAtQPs2 = getVectorAtQPs(vec2, elInfo, subAssembler, quad); + } + + void Vec2AtQP_SOT::getLALt(const ElInfo *elInfo, int nPoints, + DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + l1lt(Lambda, *(LALt[iq]), (*f)(vecAtQPs1[iq], vecAtQPs2[iq])); + } + + void Vec2AtQP_SOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + int dow = Global::getGeo(WORLD); + + if (D2UhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*f)(vecAtQPs1[iq], vecAtQPs2[iq]); + double resultQP = 0.0; + for (int i = 0; i < dow; i++) + resultQP += D2UhAtQP[iq][i][i]; + result[iq] += fac * factor * resultQP; + } + } + } + + void Vec2AtQP_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*f)(vecAtQPs1[iq], vecAtQPs2[iq]); + axpy(factor, grdUhAtQP[iq], result[iq]); + } + } + + + // ========== CoordsAtQP_SOT ========== + + void CoordsAtQP_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void CoordsAtQP_SOT::getLALt(const ElInfo *elInfo, int nPoints, + DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + l1lt(Lambda, (*LALt[iq]), (*g)(coordsAtQPs[iq])); + } + + void CoordsAtQP_SOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double f) + { + int dow = Global::getGeo(WORLD); + + if (D2UhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*g)(coordsAtQPs[iq]); + double resultQP = 0.0; + for (int i = 0; i < dow; i++) + resultQP += D2UhAtQP[iq][i][i]; + result[iq] += factor * f * resultQP; + } + } + } + + void CoordsAtQP_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*g)(coordsAtQPs[iq]); + axpy(factor, grdUhAtQP[iq], result[iq]); + } + } + + + // ========== MatrixGradient_SOT ========== + + MatrixGradient_SOT::MatrixGradient_SOT(DOFVectorBase<double> *dv, + AbstractFunction<WorldMatrix<double>, WorldVector<double> > *af, + AbstractFunction<WorldVector<double>, WorldMatrix<double> > *divAf, + bool symm) + : SecondOrderTerm(af->getDegree()), + vec(dv), + f(af), + divFct(divAf), + gradAtQPs(NULL), + symmetric(symm) + { + setSymmetric(symmetric); + + TEST_EXIT(dv)("No vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + } + + void MatrixGradient_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); + } + + void MatrixGradient_SOT::initElement(const ElInfo* smallElInfo, + const ElInfo* largeElInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + gradAtQPs = getGradientsAtQPs(vec, smallElInfo, largeElInfo, subAssembler, quad); + } + + void MatrixGradient_SOT::getLALt(const ElInfo *elInfo, int nPoints, + DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + lalt(Lambda, (*f)(gradAtQPs[iq]), (*LALt[iq]), symmetric, 1.0); + } + + void MatrixGradient_SOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) + { + int dow = Global::getGeo(WORLD); + + for (int iq = 0; iq < nPoints; iq++) { + double resultQP = 0.0; + + WorldMatrix<double> A = (*f)(gradAtQPs[iq]); + + if (D2UhAtQP) + for (int i = 0; i < dow; i++) + for (int j = 0; j < dow; j++) + resultQP += A[i][j] * D2UhAtQP[iq][j][i]; + + if (grdUhAtQP) + resultQP += (*divFct)(A) * grdUhAtQP[iq]; + + result[iq] += resultQP * factor; + } + } + + + void MatrixGradient_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + FUNCNAME("MatrixGradient_SOT::weakEval()"); + + TEST_EXIT_DBG(f)("No function f!\n"); + TEST_EXIT_DBG(gradAtQPs)("Operator was not initialized correctly!\n"); + + int nPoints = grdUhAtQP.size(); + for (int iq = 0; iq < nPoints; iq++) { + tmpMat = (*f)(gradAtQPs[iq]); + result[iq] += tmpMat * grdUhAtQP[iq]; + } + } + + + // ========== FctGradient_SOT ========== + + FctGradient_SOT::FctGradient_SOT(DOFVectorBase<double> *dv, + AbstractFunction<double, WorldVector<double> > *af) + : SecondOrderTerm(af->getDegree()), vec(dv), f(af) + { + TEST_EXIT(dv)("No vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + } + + void FctGradient_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); + } + + void FctGradient_SOT::getLALt(const ElInfo *elInfo, int nPoints, + DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + l1lt(Lambda, *(LALt[iq]), (*f)(gradAtQPs[iq])); + } + + void FctGradient_SOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + int dow = Global::getGeo(WORLD); + + if (D2UhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*f)(gradAtQPs[iq]); + double resultQP = 0.0; + for (int i = 0; i < dow; i++) + resultQP += D2UhAtQP[iq][i][i]; + result[iq] += fac * factor * resultQP; + } + } + } + + void FctGradient_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*f)(gradAtQPs[iq]); + axpy(factor, grdUhAtQP[iq], result[iq]); + } + } + + + // ========== VecMatrixGradientAtQP_SOT ========== + + VecMatrixGradientAtQP_SOT::VecMatrixGradientAtQP_SOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<WorldMatrix<double>, double, WorldVector<double> > *af, + AbstractFunction<WorldVector<double>, WorldMatrix<double> > *divAf, + bool symm) + : SecondOrderTerm(af->getDegree()), vec(dv), f(af), + divFct(divAf), symmetric(symm) + { + setSymmetric(symmetric); + + TEST_EXIT(dv)("No vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + } + + void VecMatrixGradientAtQP_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); + gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); + } + + void VecMatrixGradientAtQP_SOT::getLALt(const ElInfo *elInfo, int nPoints, + DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + lalt(Lambda, (*f)(vecAtQPs[iq], gradAtQPs[iq]), (*LALt[iq]), symmetric, 1.0); + } + + void VecMatrixGradientAtQP_SOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) + { + int dow = Global::getGeo(WORLD); + + for (int iq = 0; iq < nPoints; iq++) { + double resultQP = 0.0; + + WorldMatrix<double> A = (*f)(vecAtQPs[iq], gradAtQPs[iq]); + + if (D2UhAtQP) + for (int i = 0; i < dow; i++) + for (int j = 0; j < dow; j++) + resultQP += A[i][j] * D2UhAtQP[iq][j][i]; + + if (grdUhAtQP) + resultQP += (*divFct)(A) * grdUhAtQP[iq]; + + result[iq] += resultQP * factor; + } + } + + void VecMatrixGradientAtQP_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + WorldMatrix<double> A; + for (int iq = 0; iq < nPoints; iq++) { + A = (*f)(vecAtQPs[iq], gradAtQPs[iq]); + result[iq] += A * grdUhAtQP[iq]; + } + } + + + // ========== VecGradCoordsAtQP_SOT ========== + + VecGradCoordsAtQP_SOT::VecGradCoordsAtQP_SOT(DOFVectorBase<double> *dv, + TertiaryAbstractFunction<double, double, + WorldVector<double>, WorldVector<double> > *af) + : SecondOrderTerm(af->getDegree()), vec(dv), f(af) + { + TEST_EXIT(dv)("No vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + } + + void VecGradCoordsAtQP_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); + gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void VecGradCoordsAtQP_SOT::getLALt(const ElInfo *elInfo, int nPoints, + DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + l1lt(Lambda, *(LALt[iq]), (*f)(vecAtQPs[iq], gradAtQPs[iq], coordsAtQPs[iq])); + } + + void VecGradCoordsAtQP_SOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + int dow = Global::getGeo(WORLD); + + if (D2UhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq], coordsAtQPs[iq]); + double resultQP = 0.0; + for (int i = 0; i < dow; i++) + resultQP += D2UhAtQP[iq][i][i]; + result[iq] += fac * factor * resultQP; + } + } + } + + void VecGradCoordsAtQP_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq], coordsAtQPs[iq]); + axpy(factor, grdUhAtQP[iq], result[iq]); + } + } + + + // ========== VecAndCoordsAtQP_SOT ========== + + VecAndCoordsAtQP_SOT::VecAndCoordsAtQP_SOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<double, double, WorldVector<double> > *af) + : SecondOrderTerm(af->getDegree()), vec(dv), f(af) + { + setSymmetric(true); + + TEST_EXIT(dv)("No vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + } + + void VecAndCoordsAtQP_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void VecAndCoordsAtQP_SOT::getLALt(const ElInfo *elInfo, int nPoints, + DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + l1lt(Lambda, *(LALt[iq]), (*f)(vecAtQPs[iq], coordsAtQPs[iq])); + } + + void VecAndCoordsAtQP_SOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + int dow = Global::getGeo(WORLD); + + if (D2UhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*f)(vecAtQPs[iq], coordsAtQPs[iq]); + double resultQP = 0.0; + for (int i = 0; i < dow; i++) + resultQP += D2UhAtQP[iq][i][i]; + result[iq] += fac * factor * resultQP; + } + } + } + + void VecAndCoordsAtQP_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*f)(vecAtQPs[iq], coordsAtQPs[iq]); + axpy(factor, grdUhAtQP[iq], result[iq]); + } + } + + + // ========== MatrixGradientAndCoords_SOT ========== + + MatrixGradientAndCoords_SOT::MatrixGradientAndCoords_SOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<WorldMatrix<double>, + WorldVector<double>, WorldVector<double> > *af, + AbstractFunction<WorldVector<double>, + WorldMatrix<double> > *divAf, + bool symm) + : SecondOrderTerm(af->getDegree()), vec(dv), f(af), divFct(divAf), symmetric(symm) + { + setSymmetric(symmetric); + + TEST_EXIT(dv)("No vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + } + + void MatrixGradientAndCoords_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void MatrixGradientAndCoords_SOT::getLALt(const ElInfo *elInfo, int nPoints, + DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + lalt(Lambda, (*f)(gradAtQPs[iq], coordsAtQPs[iq]), (*LALt[iq]), symmetric, 1.0); + } + + void MatrixGradientAndCoords_SOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) + { + int dow = Global::getGeo(WORLD); + + for (int iq = 0; iq < nPoints; iq++) { + double resultQP = 0.0; + + WorldMatrix<double> A = (*f)(gradAtQPs[iq], coordsAtQPs[iq]); + + if (D2UhAtQP) + for (int i = 0; i < dow; i++) + for (int j = 0; j < dow; j++) + resultQP += A[i][j] * D2UhAtQP[iq][j][i]; + + if (grdUhAtQP) + resultQP += (*divFct)(A) * grdUhAtQP[iq]; + + result[iq] += resultQP * factor; + } + } + + void MatrixGradientAndCoords_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + WorldMatrix<double> A; + for (int iq = 0; iq < nPoints; iq++) { + A = (*f)(gradAtQPs[iq], coordsAtQPs[iq]); + result[iq] += A * grdUhAtQP[iq]; + } + } + + + // ========== MatrixVec2_SOT ========== + + MatrixVec2_SOT::MatrixVec2_SOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, + BinaryAbstractFunction<double, double, double> *f, + WorldMatrix<double> Af, + bool sym) + : SecondOrderTerm(f->getDegree()), + vec1(dv1), + vec2(dv2), + fct(f), + A(Af), + symmetric(sym) + { + FUNCNAME("MatrixVec2_SOT::MatrixVec2_SOT()"); + + setSymmetric(symmetric); + + TEST_EXIT_DBG(dv1)("No vector!\n"); + TEST_EXIT_DBG(dv2)("No vector!\n"); + + auxFeSpaces.insert(dv1->getFESpace()); + auxFeSpaces.insert(dv2->getFESpace()); + } + + void MatrixVec2_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vec1AtQPs = getVectorAtQPs(vec1, elInfo, subAssembler, quad); + vec2AtQPs = getVectorAtQPs(vec2, elInfo, subAssembler, quad); + } + + void MatrixVec2_SOT::getLALt(const ElInfo *elInfo, int nPoints, + DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + lalt(Lambda, A, *(LALt[iq]), symmetric, (*fct)(vec1AtQPs[iq], vec2AtQPs[iq])); + } + + void MatrixVec2_SOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) + { + int dow = Global::getGeo(WORLD); + + for (int iq = 0; iq < nPoints; iq++) { + double resultQP = 0.0; + + if (D2UhAtQP) + for (int i = 0; i < dow; i++) + for (int j = 0; j < dow; j++) + resultQP += A[i][j] * D2UhAtQP[iq][j][i]; + + result[iq] += resultQP * factor * (*fct)(vec1AtQPs[iq], vec2AtQPs[iq]); + } + } + + void MatrixVec2_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + for (int iq = 0; iq < nPoints; iq++) + result[iq] += A * grdUhAtQP[iq] * (*fct)(vec1AtQPs[iq], vec2AtQPs[iq]); + } + + + // ========== General_SOT ========== + + General_SOT::General_SOT(std::vector<DOFVectorBase<double>*> vecs, + std::vector<DOFVectorBase<double>*> grads, + TertiaryAbstractFunction<WorldMatrix<double>, + WorldVector<double>, + std::vector<double>, + std::vector<WorldVector<double> > > *f, + AbstractFunction<WorldVector<double>, + WorldMatrix<double> > *divFct, + bool symmetric) + : SecondOrderTerm(f->getDegree()), + vecs_(vecs), + grads_(grads), + f_(f), + divFct_(divFct), + symmetric_(symmetric) + { + vecsAtQPs_.resize(vecs_.size()); + gradsAtQPs_.resize(grads_.size()); + + for (int i = 0; i < static_cast<int>(vecs.size()); i++) { + TEST_EXIT(vecs[i])("One vector is NULL!\n"); + + auxFeSpaces.insert(vecs[i]->getFESpace()); + } + + for (int i = 0; i < static_cast<int>(grads.size()); i++) { + TEST_EXIT(grads[i])("One gradient vector is NULL!\n"); + + auxFeSpaces.insert(grads[i]->getFESpace()); + } + } + + void General_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + int nVecs = static_cast<int>(vecs_.size()); + int nGrads = static_cast<int>(grads_.size()); + + coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); + + for (int i = 0; i < nVecs; i++) + vecsAtQPs_[i] = getVectorAtQPs(vecs_[i], elInfo, subAssembler, quad); + for (int i = 0; i < nGrads; i++) + gradsAtQPs_[i] = getGradientsAtQPs(grads_[i], elInfo, subAssembler, quad); + } + + void General_SOT::getLALt(const ElInfo *elInfo, + int nPoints, + DimMat<double> **LALt) const + { + int nVecs = static_cast<int>(vecs_.size()); + int nGrads = static_cast<int>(grads_.size()); + + std::vector<double> vecsArg(nVecs); + std::vector<WorldVector<double> > gradsArg(nGrads); + + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + + for (int iq = 0; iq < nPoints; iq++) { + for (int i = 0; i < nVecs; i++) + vecsArg[i] = vecsAtQPs_[i][iq]; + for (int i = 0; i < nGrads; i++) + gradsArg[i] = gradsAtQPs_[i][iq]; + + lalt(Lambda, (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg), + *(LALt[iq]), symmetric_, 1.0); + } + } + + void General_SOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) + { + int dow = Global::getGeo(WORLD); + int nVecs = static_cast<int>(vecs_.size()); + int nGrads = static_cast<int>(grads_.size()); + + std::vector<double> vecsArg(nVecs); + std::vector<WorldVector<double> > gradsArg(nGrads); + + for (int iq = 0; iq < nPoints; iq++) { + double resultQP = 0.0; + + for (int i = 0; i < nVecs; i++) + vecsArg[i] = vecsAtQPs_[i][iq]; + for (int i = 0; i < nGrads; i++) + gradsArg[i] = gradsAtQPs_[i][iq]; + + WorldMatrix<double> A = (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg); + + if (D2UhAtQP) { + for (int i = 0; i < dow; i++) + for (int j = 0; j < dow; j++) + resultQP += A[i][j] * D2UhAtQP[iq][j][i]; + } + + if (grdUhAtQP) + resultQP += (*divFct_)(A) * grdUhAtQP[iq]; + + result[iq] += resultQP * factor; + } + } + + void General_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + int nVecs = static_cast<int>(vecs_.size()); + int nGrads = static_cast<int>(grads_.size()); + + std::vector<double> vecsArg(nVecs); + std::vector<WorldVector<double> > gradsArg(nGrads); + + WorldMatrix<double> A; + for (int iq = 0; iq < nPoints; iq++) { + for (int i = 0; i < nVecs; i++) + vecsArg[i] = vecsAtQPs_[i][iq]; + for (int i = 0; i < nGrads; i++) + gradsArg[i] = gradsAtQPs_[i][iq]; + + A = (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg); + result[iq] += A * grdUhAtQP[iq]; + } + } + + + // ========== GeneralParametric_SOT ========== + + GeneralParametric_SOT::GeneralParametric_SOT(std::vector<DOFVectorBase<double>*> vecs, + std::vector<DOFVectorBase<double>*> grads, + QuartAbstractFunction<WorldMatrix<double>, + WorldVector<double>, + WorldVector<double>, + std::vector<double>, + std::vector<WorldVector<double> > > *f, + AbstractFunction<WorldVector<double>, + WorldMatrix<double> > *divFct, + bool symmetric) + : SecondOrderTerm(f->getDegree()), + vecs_(vecs), + grads_(grads), + f_(f), + divFct_(divFct), + symmetric_(symmetric) + { + vecsAtQPs_.resize(vecs_.size()); + gradsAtQPs_.resize(grads_.size()); + + for (int i = 0; i < static_cast<int>(vecs.size()); i++) { + TEST_EXIT(vecs[i])("One vector is NULL!\n"); + + auxFeSpaces.insert(vecs[i]->getFESpace()); + } + + for (int i = 0; i < static_cast<int>(grads.size()); i++) { + TEST_EXIT(grads[i])("One gradient vector is NULL!\n"); + + auxFeSpaces.insert(grads[i]->getFESpace()); + } + } + + void GeneralParametric_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + int nVecs = static_cast<int>(vecs_.size()); + int nGrads = static_cast<int>(grads_.size()); + + elInfo->getElementNormal(elementNormal_); + coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); + + for (int i = 0; i < nVecs; i++) + vecsAtQPs_[i] = getVectorAtQPs(vecs_[i], elInfo, subAssembler, quad); + for (int i = 0; i < nGrads; i++) + gradsAtQPs_[i] = getGradientsAtQPs(grads_[i], elInfo, subAssembler, quad); + } + + void GeneralParametric_SOT::getLALt(const ElInfo *elInfo, int nPoints, + DimMat<double> **LALt) const + { + int nVecs = static_cast<int>(vecs_.size()); + int nGrads = static_cast<int>(grads_.size()); + + std::vector<double> vecsArg(nVecs); + std::vector<WorldVector<double> > gradsArg(nGrads); + + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + + for (int iq = 0; iq < nPoints; iq++) { + for (int i = 0; i < nVecs; i++) + vecsArg[i] = vecsAtQPs_[i][iq]; + for (int i = 0; i < nGrads; i++) + gradsArg[i] = gradsAtQPs_[i][iq]; + lalt(Lambda, (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg), + *(LALt[iq]), symmetric_, 1.0); + } + } + + void GeneralParametric_SOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) + { + int dow = Global::getGeo(WORLD); + int nVecs = static_cast<int>(vecs_.size()); + int nGrads = static_cast<int>(grads_.size()); + + std::vector<double> vecsArg(nVecs); + std::vector<WorldVector<double> > gradsArg(nGrads); + + for (int iq = 0; iq < nPoints; iq++) { + double resultQP = 0.0; + + for (int i = 0; i < nVecs; i++) + vecsArg[i] = vecsAtQPs_[i][iq]; + for (int i = 0; i < nGrads; i++) + gradsArg[i] = gradsAtQPs_[i][iq]; + + WorldMatrix<double> A = + (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg); + + if (D2UhAtQP) { + for (int i = 0; i < dow; i++) + for (int j = 0; j < dow; j++) + resultQP += A[i][j] * D2UhAtQP[iq][j][i]; + } + + if (grdUhAtQP) + resultQP += (*divFct_)(A) * grdUhAtQP[iq]; + + result[iq] += resultQP * factor; + } + } + + void GeneralParametric_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + int nVecs = static_cast<int>(vecs_.size()); + int nGrads = static_cast<int>(grads_.size()); + + std::vector<double> vecsArg(nVecs); + std::vector<WorldVector<double> > gradsArg(nGrads); + + WorldMatrix<double> A; + for (int iq = 0; iq < nPoints; iq++) { + for (int i = 0; i < nVecs; i++) + vecsArg[i] = vecsAtQPs_[i][iq]; + for (int i = 0; i < nGrads; i++) + gradsArg[i] = gradsAtQPs_[i][iq]; + + A = (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg); + result[iq] += A * grdUhAtQP[iq]; + } + } + + + // ========== VecAndGradAtQP_SOT ========== + + VecAndGradAtQP_SOT::VecAndGradAtQP_SOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<double, double, WorldVector<double> > *af) + : SecondOrderTerm(af->getDegree()), vec(dv), f(af) + { + TEST_EXIT(dv)("No vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + } + + void VecAndGradAtQP_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); + gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); + } + + void VecAndGradAtQP_SOT::getLALt(const ElInfo *elInfo, int nPoints, + DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + l1lt(Lambda, *(LALt[iq]), (*f)(vecAtQPs[iq], gradAtQPs[iq])); + } + + void VecAndGradAtQP_SOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + int dow = Global::getGeo(WORLD); + + if (D2UhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq]); + double resultQP = 0.0; + for (int i = 0; i < dow; i++) + resultQP += D2UhAtQP[iq][i][i]; + + result[iq] += fac * resultQP * factor; + } + } + } + + void VecAndGradAtQP_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq]); + axpy(factor, grdUhAtQP[iq], result[iq]); + } + } + + + // ========== VecGrad_SOT ========== + + void VecGrad_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = subAssembler->getVectorAtQPs(vec1, elInfo, quad); + gradAtQPs = subAssembler->getGradientsAtQPs(vec2, elInfo, quad); + } + + void VecGrad_SOT::getLALt(const ElInfo *elInfo, int nPoints, + DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + l1lt(Lambda, *(LALt[iq]), (*f)(vecAtQPs[iq], gradAtQPs[iq])); + } + + void VecGrad_SOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + int dow = Global::getGeo(WORLD); + + if (D2UhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq]); + double resultQP = 0.0; + for (int i = 0; i < dow; i++) + resultQP += D2UhAtQP[iq][i][i]; + result[iq] += fac * resultQP * factor; + } + } + } + + void VecGrad_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq]); + axpy(factor, grdUhAtQP[iq], result[iq]); + } + } + + + // ========== CoordsAtQP_IJ_SOT ========== + + void CoordsAtQP_IJ_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void CoordsAtQP_IJ_SOT::getLALt(const ElInfo *elInfo, + int nPoints, + DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + lalt_kl(Lambda, xi, xj, *(LALt[iq]), (*g)(coordsAtQPs[iq])); + } + + void CoordsAtQP_IJ_SOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double f) + { + if (D2UhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*g)(coordsAtQPs[iq]); + result[iq] += D2UhAtQP[iq][xi][xj] * factor * f; + } + } + } + + void CoordsAtQP_IJ_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*g)(coordsAtQPs[iq]); + result[iq][xi] += grdUhAtQP[iq][xj] * factor; + } + } + + + // ========== VecAtQP_IJ_SOT ========== + + VecAtQP_IJ_SOT::VecAtQP_IJ_SOT(DOFVectorBase<double> *dv, + AbstractFunction<double, double> *af, + int x_i, int x_j) + : SecondOrderTerm(af->getDegree()), vec(dv), f(af), xi(x_i), xj(x_j) + { + setSymmetric(xi == xj); + + TEST_EXIT(dv)("No vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + } + + void VecAtQP_IJ_SOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); + } + + void VecAtQP_IJ_SOT::getLALt(const ElInfo *elInfo, + int nPoints, + DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) { + lalt_kl(Lambda, xi, xj, *(LALt[iq]), (*f)(vecAtQPs[iq])); + } + } + + void VecAtQP_IJ_SOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + if (D2UhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*f)(vecAtQPs[iq]); + result[iq] += D2UhAtQP[iq][xi][xj] * factor * fac; + } + } + } + + void VecAtQP_IJ_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + for (int iq = 0; iq < nPoints; iq++) { + double factor = (*f)(vecAtQPs[iq]); + result[iq][xi] += grdUhAtQP[iq][xj] * factor; + } + } + + +} diff --git a/AMDiS/src/SecondOrderTerm.h b/AMDiS/src/SecondOrderTerm.h new file mode 100644 index 00000000..74e6b441 --- /dev/null +++ b/AMDiS/src/SecondOrderTerm.h @@ -0,0 +1,1190 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == TU Dresden == +// == == +// == Institut f�r Wissenschaftliches Rechnen == +// == Zellescher Weg 12-14 == +// == 01069 Dresden == +// == germany == +// == == +// ============================================================================ +// == == +// == https://gforge.zih.tu-dresden.de/projects/amdis/ == +// == == +// ============================================================================ + +/** \file SecondOrderTerm.h */ + +#ifndef AMDIS_SECOND_ORDER_TERM_H +#define AMDIS_SECOND_ORDER_TERM_H + +#include "AMDiS_fwd.h" +#include "OperatorTerm.h" +#include "ElInfo.h" +#include "AbstractFunction.h" + +namespace AMDiS { + + /** + * \ingroup Assembler + * + * \brief + * Describes the second order terms: \f$ \nabla \cdot A \nabla u(\vec{x}) \f$ + */ + class SecondOrderTerm : public OperatorTerm + { + public: + /// Constructor. + SecondOrderTerm(int deg) + : OperatorTerm(deg) + {} + + /// Destructor. + virtual ~SecondOrderTerm() + {} + + /// Evaluation of \f$ \Lambda A \Lambda^t \f$ at all quadrature points. + virtual void getLALt(const ElInfo *elInfo, + int nPoints, + DimMat<double> **result) const = 0; + + /// Evaluation of \f$ A \nabla u(\vec{x}) \f$ at all quadrature points. + virtual void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) = 0; + }; + + + /** + * \ingroup Assembler + * + * \brief + * Implements the laplace operator: \f$ \Delta u(\vec{x}) \f$ + */ + class Laplace_SOT : public SecondOrderTerm + { + public: + /// Constructor. + Laplace_SOT() + : SecondOrderTerm(0) + { + setSymmetric(true); + } + + /// Implenetation of SecondOrderTerm::getLALt(). + inline void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + + for (int iq = 0; iq < nPoints; iq++) + l1lt(Lambda, *(LALt[iq]), 1.0); + } + + /// Implementation of SecondOrderTerm::eval(). + inline void eval(int nPoints, + const double *, + const WorldVector<double> *, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor) + { + int dow = Global::getGeo(WORLD); + + if (D2UhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + double resultQP = 0.0; + for (int i = 0; i < dow; i++) + resultQP += D2UhAtQP[iq][i][i]; + result[iq] += factor * resultQP; + } + } + } + + /// Implenetation of SecondOrderTerm::weakEval(). + void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + for (int iq = 0; iq < nPoints; iq++) + result[iq] += grdUhAtQP[iq]; + } + }; + + + /** + * \ingroup Assembler + * + * \brief + * Implements the laplace operator multiplied with a scalar factor: + * \f$ f \cdot \Delta u(\vec{x}) \f$ + */ + class FactorLaplace_SOT : public SecondOrderTerm + { + public: + /// Constructor. + FactorLaplace_SOT(double f) + : SecondOrderTerm(0) + { + factor = new double; + *factor = f; + + setSymmetric(true); + } + + /// Constructor. + FactorLaplace_SOT(double *fptr) + : SecondOrderTerm(0), + factor(fptr) + { + setSymmetric(true); + } + + /// Implements SecondOrderTerm::getLALt(). + inline void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + l1lt(Lambda, *(LALt[iq]), (*factor)); + } + + /// Implenetation of SecondOrderTerm::eval(). + void eval(int nPoints, + const double *, + const WorldVector<double> *, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double f) + { + int dow = Global::getGeo(WORLD); + + if (D2UhAtQP) { + for (int iq = 0; iq < nPoints; iq++) { + double resultQP = 0.0; + for (int i = 0; i < dow; i++) { + resultQP += D2UhAtQP[iq][i][i]; + } + result[iq] += resultQP * f * (*factor); + } + } + } + + /// Implenetation of SecondOrderTerm::weakEval(). + void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + for (int iq = 0; iq < nPoints; iq++) + axpy(*factor, grdUhAtQP[iq], result[iq]); + } + + private: + /// Pointer to the factor. + double *factor; + }; + + + /** + * \ingroup Assembler + * + * \brief + * SecondOrderTerm where A is a function which maps a DOFVector evaluated at + * a given quadrature point to a WolrdMatrix: + * \f$ \nabla \cdot A(v(\vec{x})) \nabla u(\vec{x}) \f$ + */ + class MatrixFct_SOT : public SecondOrderTerm + { + public: + /// Constructor. + MatrixFct_SOT(DOFVectorBase<double> *dv, + AbstractFunction<WorldMatrix<double>, double> *fct, + AbstractFunction<WorldVector<double>, WorldMatrix<double> > *div, + bool sym = false); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements SecondOrderTerm::getLALt(). + void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; + + /// Implenetation of SecondOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + /// Implenetation of 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>* vec; + + /// Pointer to the values of the DOFVector at quadrature points. + double* vecAtQPs; + + /// Function for A. + AbstractFunction<WorldMatrix<double>, double>* matrixFct; + + /// + AbstractFunction<WorldVector<double>, WorldMatrix<double> >* divFct; + + /// True, if \ref matrixFct produces always symmetric matrices. + bool symmetric; + }; + + + /** + * \ingroup Assembler + * + * \brief + * SecondOrderTerm where A is a given fixed WorldMatrix<double>: + * \f$ \nabla \cdot A \nabla u(\vec{x}) \f$ + */ + class Matrix_SOT : public SecondOrderTerm { + public: + /// Constructor + Matrix_SOT(WorldMatrix<double> mat) + : SecondOrderTerm(0), matrix(mat) + { + symmetric = matrix.isSymmetric(); + setSymmetric(symmetric); + } + + /// Implements SecondOrderTerm::getLALt(). + inline void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> >& Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + lalt(Lambda, matrix, *(LALt[iq]), symmetric, 1.0); + } + + /// Implenetation of SecondOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + /// Implenetation of SecondOrderTerm::weakEval(). + void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result); + + protected: + /// Matrix stroring A. + WorldMatrix<double> matrix; + + /// True, if \ref matrix is symmetric. + bool symmetric; + }; + + + /** + * \ingroup Assembler + * + * \brief + * SecondOrderTerm where A is a WorldMatrix<double> having a ONE in position IJ + * and ZERO in all other positions + * \f$ \nabla \cdot A \nabla u(\vec{x}) \f$ + */ + class FactorIJ_SOT : public SecondOrderTerm + { + public: + /// Constructor. + FactorIJ_SOT(int x_i, int x_j, double f) + : SecondOrderTerm(0), xi(x_i), xj(x_j) + { + factor = new double; + *factor = f; + + setSymmetric(xi == xj); + } + + /// Constructor. + FactorIJ_SOT(int x_i, int x_j, double *fptr) + : SecondOrderTerm(0), xi(x_i), xj(x_j), factor(fptr) + { + setSymmetric(xi == xj); + } + + /// Implements SecondOrderTerm::getLALt(). + inline void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const + { + const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda(); + for (int iq = 0; iq < nPoints; iq++) + lalt_kl(Lambda, xi, xj, *(LALt[iq]), (*factor)); + } + + /// Implenetation of SecondOrderTerm::eval(). + void eval(int nPoints, + const double *, + const WorldVector<double> *, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + if (D2UhAtQP) + for (int iq = 0; iq < nPoints; iq++) + result[iq] += (*factor) * D2UhAtQP[iq][xi][xj] * fac; + } + + /// Implenetation of SecondOrderTerm::weakEval(). + void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result) + { + int nPoints = grdUhAtQP.size(); + for (int iq = 0; iq < nPoints; iq++) + result[iq][xi] += (*factor) * grdUhAtQP[iq][xj]; + } + + private: + /// Directions for the derivatives. + int xi, xj; + + /// Pointer to the factor. + double *factor; + }; + + + /** + * \ingroup Assembler + * + * \brief + * Laplace operator multiplied with a function evaluated at the quadrature + * points of a given DOFVector: + * \f$ f(v(\vec{x})) \Delta u(\vec{x}) \f$ + */ + class VecAtQP_SOT : public SecondOrderTerm { + public: + /// Constructor. + VecAtQP_SOT(DOFVectorBase<double> *dv, AbstractFunction<double, double> *af); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implementation of \ref OperatorTerm::initElement() for multilpe meshes. + void initElement(const ElInfo* smallElInfo, + const ElInfo* largeElInfo, + SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements SecondOrderTerm::getLALt(). + void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; + + /// Implenetation of SecondOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + /// Implenetation of 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>* vec; + + /// Pointer to an array containing the DOFVector evaluated at quadrature points. + double* vecAtQPs; + + /// Function evaluated at \ref vecAtQPs. + AbstractFunction<double, double> *f; + }; + + /** + * \ingroup Assembler + * + * \brief + * Laplace operator multiplied with a function evaluated at the quadrature + * points of a given DOFVector: + * \f$ f(v(\vec{x}), w(\vec{x})) \Delta u(\vec{x}) \f$ + */ + class Vec2AtQP_SOT : public SecondOrderTerm { + public: + /// Constructor. + Vec2AtQP_SOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, + BinaryAbstractFunction<double, double, double> *af); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements SecondOrderTerm::getLALt(). + void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; + + /// Implenetation of SecondOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + /// Implenetation of 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. + double* vecAtQPs1; + double* vecAtQPs2; + + /// Function evaluated at \ref vecAtQPs. + BinaryAbstractFunction<double, double, double> *f; + }; + + + /** + * \ingroup Assembler + * + * \brief + * Laplace multiplied with a function evaluated at each quadrature point: + * \f$ f(\vec{x}) \Delta u(\vec{x}) \f$ + */ + class CoordsAtQP_SOT : public SecondOrderTerm { + public: + /// Constructor. + CoordsAtQP_SOT(AbstractFunction<double, WorldVector<double> > *af) + : SecondOrderTerm(af->getDegree()), g(af) + { + setSymmetric(true); + } + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements SecondOrderTerm::getLALt(). + void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; + + /// Implenetation of SecondOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + /// Implenetation of SecondOrderTerm::weakEval(). + void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result); + + + protected: + /// Stores coordinates at quadrature points. Set in \ref initElement(). + WorldVector<double>* coordsAtQPs; + + /// Function evaluated at quadrature points. + AbstractFunction<double, WorldVector<double> > *g; + }; + + + /** + * \ingroup Assembler + * + * \brief + * SecondOrderTerm where A is a function which maps the gradient of a + * DOFVector at each quadrature point to WorldMatrix<double>: + * \f$ \nabla \cdot A(\nabla v(\vec{x})) \nabla u(\vec{x})\f$ + */ + class MatrixGradient_SOT : public SecondOrderTerm + { + public: + /// Constructor. + MatrixGradient_SOT(DOFVectorBase<double> *dv, + AbstractFunction<WorldMatrix<double>, WorldVector<double> > *af, + AbstractFunction<WorldVector<double>, WorldMatrix<double> > *divAf, + bool symm = false); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implementation of \ref OperatorTerm::initElement() for multilpe meshes. + void initElement(const ElInfo* smallElInfo, + const ElInfo* largeElInfo, + SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements SecondOrderTerm::getLALt(). + void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; + + /// Implenetation of SecondOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + /// Implenetation of SecondOrderTerm::weakEval(). + void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result); + + protected: + DOFVectorBase<double>* vec; + + /// Function which maps each entry in \ref gradAtQPs to a WorldMatrix<double>. + AbstractFunction<WorldMatrix<double>, WorldVector<double> > *f; + + AbstractFunction<WorldVector<double>, WorldMatrix<double> > *divFct; + + /** \brief + * Pointer to a WorldVector<double> array containing the gradients of the DOFVector + * at each quadrature point. + */ + WorldVector<double>* gradAtQPs; + + /// True, if \ref f provides always a symmetric WorldMatrix<double>. + bool symmetric; + + private: + /// Temporary matrix used in \ref MatrixGradient_SOT::weakEval. + WorldMatrix<double> tmpMat; + }; + + + /** + * \ingroup Assembler + * + * \brief + * Laplace multiplied with a function which maps the gradient of a DOFVector + * at each quadrature point to a double: + * \f$ f(\nabla v(\vec{x})) \Delta u(\vec{x}) \f$ + */ + class FctGradient_SOT : public SecondOrderTerm + { + public: + /// Constructor. + FctGradient_SOT(DOFVectorBase<double> *dv, + AbstractFunction<double, WorldVector<double> > *af); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements SecondOrderTerm::getLALt(). + void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; + + /// Implenetation of SecondOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + /// Implenetation of SecondOrderTerm::weakEval(). + void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result); + + protected: + DOFVectorBase<double>* vec; + + /// Function wich maps \ref gradAtQPs to a double. + AbstractFunction<double, WorldVector<double> > *f; + + /** \brief + * Pointer to a WorldVector<double> array containing the gradients of the DOFVector + * at each quadrature point. + */ + WorldVector<double>* gradAtQPs; + }; + + + /** + * \ingroup Assembler + * + * \brief + * Laplace multiplied with a function which maps the gradient of a DOFVector + * at each quadrature point to a double: + * \f$ \nabla \cdot A(v(\vec{x}), \nabla v(\vec{x})) \nabla u(\vec{x}) \f$ + */ + class VecMatrixGradientAtQP_SOT : public SecondOrderTerm + { + public: + /// Constructor. + VecMatrixGradientAtQP_SOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<WorldMatrix<double>, double, WorldVector<double> > *af, + AbstractFunction<WorldVector<double>, WorldMatrix<double> > *divAf, + bool symm = false); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements SecondOrderTerm::getLALt(). + void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; + + /// Implenetation of SecondOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + /// Implenetation of SecondOrderTerm::weakEval(). + void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result); + + protected: + DOFVectorBase<double>* vec; + + /// Function wich maps \ref gradAtQPs to a double. + BinaryAbstractFunction<WorldMatrix<double>, + double, WorldVector<double> > *f; + + AbstractFunction<WorldVector<double>, WorldMatrix<double> > *divFct; + + /** \brief + * Pointer to a WorldVector<double> array containing the gradients of the DOFVector + * at each quadrature point. + */ + double* vecAtQPs; + WorldVector<double>* gradAtQPs; + + bool symmetric; + }; + + + /** + * \ingroup Assembler + * + * \brief + * Laplace multiplied with a function which maps the gradient of a DOFVector + * at each quadrature point to a double: + * \f$ f(\nabla v(\vec{x})) \Delta u(\vec{x}) \f$ + */ + class VecGradCoordsAtQP_SOT : public SecondOrderTerm + { + public: + /// Constructor. + VecGradCoordsAtQP_SOT(DOFVectorBase<double> *dv, + TertiaryAbstractFunction<double, double, + WorldVector<double>, WorldVector<double> > *af); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements SecondOrderTerm::getLALt(). + void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; + + /// Implenetation of SecondOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + /// Implenetation of SecondOrderTerm::weakEval(). + void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result); + + protected: + DOFVectorBase<double>* vec; + + /// Function wich maps \ref gradAtQPs to a double. + TertiaryAbstractFunction<double, double, WorldVector<double>, + WorldVector<double> > *f; + + /** \brief + * Pointer to a WorldVector<double> array containing the gradients of the DOFVector + * at each quadrature point. + */ + double* vecAtQPs; + WorldVector<double>* gradAtQPs; + WorldVector<double>* coordsAtQPs; + + }; + + + /** + * \ingroup Assembler + * + * \brief + * Laplace operator multiplied with a function evaluated at the quadrature + * points of a given DOFVector: + * \f$ -f(v(\vec{x})) \Delta u(\vec{x}) \f$ + */ + class VecAndCoordsAtQP_SOT : public SecondOrderTerm { + public: + /// Constructor. + VecAndCoordsAtQP_SOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<double, double, WorldVector<double> > *af); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements SecondOrderTerm::eval(). + void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; + + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result); + + protected: + /// DOFVector to be evaluated at quadrature points. + DOFVectorBase<double>* vec; + + /// Pointer to an array containing the DOFVector evaluated at quadrature points. + double* vecAtQPs; + + WorldVector<double>* coordsAtQPs; + + /// Function evaluated at \ref vecAtQPs. + BinaryAbstractFunction<double, double, WorldVector<double> > *f; + }; + + + /** + * \ingroup Assembler + * + * \brief + * SecondOrderTerm where A is a function which maps the gradient of a + * DOFVector at each quadrature point to WorldMatrix<double>: + * \f$ \nabla \cdot A(\nabla v(\vec{x})) \nabla u(\vec{x})\f$ + */ + class MatrixGradientAndCoords_SOT : public SecondOrderTerm + { + public: + /// Constructor. + MatrixGradientAndCoords_SOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<WorldMatrix<double>, + WorldVector<double> , + WorldVector<double> > *af, + AbstractFunction<WorldVector<double>, + WorldMatrix<double> > *divAf, + bool symm = false); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements SecondOrderTerm::getLALt(). + void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; + + /// Implenetation of SecondOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + /// Implenetation of SecondOrderTerm::weakEval(). + void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result); + + protected: + DOFVectorBase<double>* vec; + + /// Function which maps each entry in \ref gradAtQPs to a WorldMatrix<double>. + BinaryAbstractFunction<WorldMatrix<double>, + WorldVector<double>, WorldVector<double> > *f; + + AbstractFunction<WorldVector<double>, WorldMatrix<double> > *divFct; + + /** \brief + * Pointer to a WorldVector<double> array containing the gradients of the DOFVector + * at each quadrature point. + */ + WorldVector<double>* gradAtQPs; + + WorldVector<double>* coordsAtQPs; + + /// True, if \ref f provides always a symmetric WorldMatrix<double>. + bool symmetric; + }; + + + class MatrixVec2_SOT : public SecondOrderTerm + { + public: + /// Constructor. + MatrixVec2_SOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, + BinaryAbstractFunction<double, double, double> *f, + WorldMatrix<double> Af, + bool sym = false); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements SecondOrderTerm::getLALt(). + void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; + + /// Implenetation of SecondOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + /// Implenetation of 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 the values of the DOFVector at quadrature points. + double* vec1AtQPs; + double* vec2AtQPs; + + /// Function for A. + BinaryAbstractFunction<double, double, double> * fct; + + /// + WorldMatrix<double> A; + + /// True, if \ref matrixFct produces always symmetric matrices. + bool symmetric; + }; + + + class General_SOT : public SecondOrderTerm + { + public: + /// Constructor. + General_SOT(std::vector<DOFVectorBase<double>*> vecs, + std::vector<DOFVectorBase<double>*> grads, + TertiaryAbstractFunction<WorldMatrix<double>, + WorldVector<double>, + std::vector<double>, + std::vector<WorldVector<double> > > *f, + AbstractFunction<WorldVector<double>, + WorldMatrix<double> > *divFct, + bool symmetric); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo*, SubAssembler*, Quadrature *quad= NULL); + + /// Implements SecondOrderTerm::getLALt(). + void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; + + /// Implenetation of SecondOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + /// Implenetation of SecondOrderTerm::weakEval(). + void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result); + + protected: + std::vector<DOFVectorBase<double>*> vecs_; + + std::vector<DOFVectorBase<double>*> grads_; + + TertiaryAbstractFunction<WorldMatrix<double>, + WorldVector<double>, + std::vector<double>, + std::vector<WorldVector<double> > > *f_; + + AbstractFunction<WorldVector<double>, + WorldMatrix<double> > *divFct_; + + WorldVector<double> *coordsAtQPs_; + + std::vector<double*> vecsAtQPs_; + + std::vector<WorldVector<double>*> gradsAtQPs_; + + bool symmetric_; + }; + + + class GeneralParametric_SOT : public SecondOrderTerm + { + public: + /// Constructor. + GeneralParametric_SOT(std::vector<DOFVectorBase<double>*> vecs, + std::vector<DOFVectorBase<double>*> grads, + QuartAbstractFunction<WorldMatrix<double>, + WorldVector<double>, + WorldVector<double>, + std::vector<double>, + std::vector<WorldVector<double> > > *f, + AbstractFunction<WorldVector<double>, + WorldMatrix<double> > *divFct, + bool symmetric); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo*, + SubAssembler* , + Quadrature *quad= NULL); + + /// Implements SecondOrderTerm::getLALt(). + void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; + + /// Implenetation of SecondOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + /// Implenetation of SecondOrderTerm::weakEval(). + void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result); + + protected: + std::vector<DOFVectorBase<double>*> vecs_; + + std::vector<DOFVectorBase<double>*> grads_; + + QuartAbstractFunction<WorldMatrix<double>, + WorldVector<double>, + WorldVector<double>, + std::vector<double>, + std::vector<WorldVector<double> > > *f_; + + AbstractFunction<WorldVector<double>, + WorldMatrix<double> > *divFct_; + + WorldVector<double> *coordsAtQPs_; + WorldVector<double> elementNormal_; + + std::vector<double*> vecsAtQPs_; + + std::vector<WorldVector<double>*> gradsAtQPs_; + + bool symmetric_; + }; + + + /** + * \ingroup Assembler + * + * \brief + * Laplace multiplied with a function which maps the gradient of a DOFVector + * at each quadrature point to a double: + * \f$ f(\nabla v(\vec{x})) \Delta u(\vec{x}) \f$ + */ + class VecAndGradAtQP_SOT : public SecondOrderTerm + { + public: + /// Constructor. + VecAndGradAtQP_SOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<double, double, WorldVector<double> > *af); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + + /// Implements SecondOrderTerm::getLALt(). + void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; + + /// Implements SecondOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + 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>* vec; + + /// Vector v at quadrature points. + double *vecAtQPs; + + /// Gradient at quadrature points. + WorldVector<double> *gradAtQPs; + + /// Function for c. + BinaryAbstractFunction<double, double, WorldVector<double> > *f; + }; + + + /** + * \ingroup Assembler + * + * \brief + * Second order term: \f$ f(v(\vec{x}),\nabla w(\vec{x})) \Delta u(\vec{x})\f$ + */ + class VecGrad_SOT : public SecondOrderTerm + { + public: + /// Constructor. + VecGrad_SOT( DOFVectorBase<double> *dv1, + DOFVectorBase<double> *dv2, + BinaryAbstractFunction<double, double, WorldVector<double> > *f_) + : SecondOrderTerm(f_->getDegree()), vec1(dv1), vec2(dv2), f(f_) + {} + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements SecondOrderTerm::getLALt(). + inline void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; + + /// Implements SecondOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + /// Implements SecondOrderTerm::weakEval(). + void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result); + + protected: + /// DOFVectors to be evaluated at quadrature points. + DOFVectorBase<double>* vec1; + DOFVectorBase<double>* vec2; + + /// Vector v at quadrature points. + double *vecAtQPs; + + /// Gradient at quadrature points. + WorldVector<double> *gradAtQPs; + + /// Function for c. + BinaryAbstractFunction<double, double, WorldVector<double> > *f; + }; + + + /** + * \ingroup Assembler + * + * \brief + * SecondOrderTerm where A(x) is a WorldMatrix having a in all positions + * except possibly the position IJ + * \f$ \nabla \cdot A(x) \nabla u(\vec{x}) \f$ + */ + class CoordsAtQP_IJ_SOT : public SecondOrderTerm + { + public: + /// Constructor. + CoordsAtQP_IJ_SOT(AbstractFunction<double, WorldVector<double> > *af, + int x_i, int x_j) + : SecondOrderTerm(af->getDegree()), g(af), xi(x_i), xj(x_j) + { + setSymmetric(xi == xj); + } + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements SecondOrderTerm::getLALt(). + inline void getLALt(const ElInfo *elInfo, int nPoints, DimMat<double> **LALt) const; + + /// Implements SecondOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double factor); + + /// Implements SecondOrderTerm::weakEval(). + void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP, + std::vector<WorldVector<double> > &result); + + private: + /// Stores coordinates at quadrature points. Set in \ref initElement(). + WorldVector<double>* coordsAtQPs; + + /// Function evaluated at quadrature points. + AbstractFunction<double, WorldVector<double> > *g; + + /// Directions for the derivatives. + 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 a given DOFVector: + * \f$ \nabla \cdot f(v(\vec{x})) A \nabla u(\vec{x}) \f$ + */ + class VecAtQP_IJ_SOT : public SecondOrderTerm + { + public: + /// Constructor. + VecAtQP_IJ_SOT(DOFVectorBase<double> *dv, AbstractFunction<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, int nPoints, DimMat<double> **LALt) const; + + /// Implements SecondOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + 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>* vec; + + /// Pointer to an array containing the DOFVector evaluated at quadrature points. + double* vecAtQPs; + + /// Function evaluated at \ref vecAtQPs. + AbstractFunction<double, double> *f; + + private: + /// Directions for the derivatives. + int xi, xj; + }; + +} + +#endif diff --git a/AMDiS/src/ZeroOrderTerm.cc b/AMDiS/src/ZeroOrderTerm.cc new file mode 100644 index 00000000..d97cd6d3 --- /dev/null +++ b/AMDiS/src/ZeroOrderTerm.cc @@ -0,0 +1,1026 @@ +#include "ZeroOrderTerm.h" +#include "DOFVector.h" + +namespace AMDiS { + + // ========== VecAtQP_ZOT ========== + + VecAtQP_ZOT::VecAtQP_ZOT(DOFVectorBase<double> *dv, + AbstractFunction<double, double> *af) + : ZeroOrderTerm(af ? af->getDegree() : 0), vec(dv), f(af) + { + TEST_EXIT(dv)("No vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + } + + void VecAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); + } + + void VecAtQP_ZOT::initElement(const ElInfo* smallElInfo, + const ElInfo* largeElInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = getVectorAtQPs(vec, smallElInfo, largeElInfo, subAssembler, quad); + } + + void VecAtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) + { + if (f) { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += (*f)(vecAtQPs[iq]); + } else { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += vecAtQPs[iq]; + } + } + + void VecAtQP_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + if (f) { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += fac * (*f)(vecAtQPs[iq]) * uhAtQP[iq]; + } else { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += fac * vecAtQPs[iq] * uhAtQP[iq]; + } + } + + + // ========== MultVecAtQP_ZOT ========== + + MultVecAtQP_ZOT::MultVecAtQP_ZOT(DOFVectorBase<double> *dv1, + DOFVectorBase<double> *dv2, + AbstractFunction<double, double> *af1, + AbstractFunction<double, double> *af2) + : ZeroOrderTerm(af1->getDegree() + af2->getDegree()), + vec1(dv1), vec2(dv2), f1(af1), f2(af2) + { + TEST_EXIT(dv1)("No first vector!\n"); + TEST_EXIT(dv2)("No second vector!\n"); + + auxFeSpaces.insert(dv1->getFESpace()); + auxFeSpaces.insert(dv2->getFESpace()); + } + + void MultVecAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs1 = getVectorAtQPs(vec1, elInfo, subAssembler, quad); + vecAtQPs2 = getVectorAtQPs(vec2, elInfo, subAssembler, quad); + } + + void MultVecAtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) + { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += (*f1)(vecAtQPs1[iq]) * (*f2)(vecAtQPs2[iq]); + } + + void MultVecAtQP_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += fac * (*f1)(vecAtQPs1[iq]) * (*f2)(vecAtQPs2[iq]) * uhAtQP[iq]; + } + + + // ========== Vec2AtQP_ZOT ========== + + Vec2AtQP_ZOT::Vec2AtQP_ZOT(DOFVectorBase<double> *dv1, + DOFVectorBase<double> *dv2, + BinaryAbstractFunction<double, double, double> *af) + : ZeroOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), f(af) + { + TEST_EXIT(dv1)("No first vector!\n"); + TEST_EXIT(dv2)("No second vector!\n"); + + auxFeSpaces.insert(dv1->getFESpace()); + auxFeSpaces.insert(dv2->getFESpace()); + } + + void Vec2AtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs1 = getVectorAtQPs(vec1, elInfo, subAssembler, quad); + vecAtQPs2 = getVectorAtQPs(vec2, elInfo, subAssembler, quad); + } + + void Vec2AtQP_ZOT::initElement(const ElInfo* smallElInfo, + const ElInfo* largeElInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + TEST_EXIT(vec1->getFESpace() == vec2->getFESpace())("Not yet implemented!\n"); + + vecAtQPs1 = getVectorAtQPs(vec1, smallElInfo, largeElInfo, subAssembler, quad); + vecAtQPs2 = getVectorAtQPs(vec2, smallElInfo, largeElInfo, subAssembler, quad); + } + + void Vec2AtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) + { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += (*f)(vecAtQPs1[iq], vecAtQPs2[iq]); + } + + void Vec2AtQP_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += fac * (*f)(vecAtQPs1[iq], vecAtQPs2[iq]) * uhAtQP[iq]; + } + + + // ========== Vec3AtQP_ZOT ========== + + Vec3AtQP_ZOT::Vec3AtQP_ZOT(DOFVectorBase<double> *dv1, + DOFVectorBase<double> *dv2, + DOFVectorBase<double> *dv3, + TertiaryAbstractFunction<double, double, double, double> *af) + : ZeroOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), vec3(dv3), f(af) + { + TEST_EXIT(dv1)("No first vector!\n"); + TEST_EXIT(dv2)("No second vector!\n"); + TEST_EXIT(dv3)("No thierd vector!\n"); + + auxFeSpaces.insert(dv1->getFESpace()); + auxFeSpaces.insert(dv2->getFESpace()); + auxFeSpaces.insert(dv3->getFESpace()); + } + + void Vec3AtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs1 = getVectorAtQPs(vec1, elInfo, subAssembler, quad); + vecAtQPs2 = getVectorAtQPs(vec2, elInfo, subAssembler, quad); + vecAtQPs3 = getVectorAtQPs(vec3, elInfo, subAssembler, quad); + } + + void Vec3AtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) + { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += (*f)(vecAtQPs1[iq], vecAtQPs2[iq], vecAtQPs3[iq]); + } + + void Vec3AtQP_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += + fac * (*f)(vecAtQPs1[iq], vecAtQPs2[iq], vecAtQPs3[iq]) * uhAtQP[iq]; + } + + + // ========== FctGradientCoords_ZOT ========== + + FctGradientCoords_ZOT::FctGradientCoords_ZOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<double, WorldVector<double>, WorldVector<double> > *af) + : ZeroOrderTerm(af->getDegree()), vec(dv), f(af) + { + TEST_EXIT(dv)("No vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + } + + void FctGradientCoords_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void FctGradientCoords_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) + { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += (*f)(gradAtQPs[iq], coordsAtQPs[iq]); + } + + void FctGradientCoords_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += + fac * (*f)(gradAtQPs[iq], coordsAtQPs[iq]) * uhAtQP[iq]; + } + + + // ========== VecGradCoordsAtQP_ZOT ========== + + VecGradCoordsAtQP_ZOT::VecGradCoordsAtQP_ZOT(DOFVectorBase<double> *dv, + TertiaryAbstractFunction<double, double, WorldVector<double>, WorldVector<double> > *af) + : ZeroOrderTerm(af->getDegree()), vec(dv), f(af) + { + TEST_EXIT(dv)("No vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + } + + void VecGradCoordsAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); + gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void VecGradCoordsAtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) + { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += (*f)(vecAtQPs[iq], gradAtQPs[iq], coordsAtQPs[iq]); + } + + void VecGradCoordsAtQP_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += + fac * + (*f)(vecAtQPs[iq], gradAtQPs[iq], coordsAtQPs[iq]) * + uhAtQP[iq]; + } + + + // ========== VecAndCoordsAtQP_ZOT ========== + + VecAndCoordsAtQP_ZOT::VecAndCoordsAtQP_ZOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<double, double, WorldVector<double> > *af) + : ZeroOrderTerm(af->getDegree()), vec(dv), f(af) + { + TEST_EXIT(dv)("No vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + } + + void VecAndCoordsAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void VecAndCoordsAtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) + { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += (*f)(vecAtQPs[iq], coordsAtQPs[iq]); + } + + void VecAndCoordsAtQP_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += fac * (*f)(vecAtQPs[iq], coordsAtQPs[iq]) * uhAtQP[iq]; + } + + + // ========== Vec2AndGradAtQP_ZOT ========== + + Vec2AndGradAtQP_ZOT::Vec2AndGradAtQP_ZOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, + TertiaryAbstractFunction<double, double, WorldVector<double>, double > *af) + : ZeroOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), f(af) + { + TEST_EXIT(dv1)("No first vector!\n"); + TEST_EXIT(dv2)("No second vector!\n"); + + auxFeSpaces.insert(dv1->getFESpace()); + auxFeSpaces.insert(dv2->getFESpace()); + } + + void Vec2AndGradAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs1 = getVectorAtQPs(vec1, elInfo, subAssembler, quad); + vecAtQPs2 = getVectorAtQPs(vec2, elInfo, subAssembler, quad); + gradAtQPs = getGradientsAtQPs(vec1, elInfo, subAssembler, quad); + } + + void Vec2AndGradAtQP_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += + fac * + (*f)(vecAtQPs1[iq], gradAtQPs[iq], vecAtQPs2[iq]) * + uhAtQP[iq]; + } + + void Vec2AndGradAtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) + { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += (*f)(vecAtQPs1[iq], gradAtQPs[iq], vecAtQPs2[iq]); + } + + + // ========== FctGradient_ZOT ========== + + FctGradient_ZOT::FctGradient_ZOT(DOFVectorBase<double> *dv, + AbstractFunction<double, WorldVector<double> > *af) + : ZeroOrderTerm(af->getDegree()), vec(dv), f(af) + { + TEST_EXIT(dv)("No vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + } + + void FctGradient_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); + } + + void FctGradient_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) + { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += (*f)(gradAtQPs[iq]); + } + + void FctGradient_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += fac * (*f)(gradAtQPs[iq]) * uhAtQP[iq]; + } + + + // ========== VecAndGradAtQP_ZOT ========== + + VecAndGradAtQP_ZOT::VecAndGradAtQP_ZOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<double, double, WorldVector<double> > *af) + : ZeroOrderTerm(af->getDegree()), vec(dv), f(af) + { + TEST_EXIT(dv)("No vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + } + + void VecAndGradAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); + gradAtQPs = getGradientsAtQPs(vec, elInfo, subAssembler, quad); + } + + void VecAndGradAtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) + { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += (*f)(vecAtQPs[iq], gradAtQPs[iq]); + } + + void VecAndGradAtQP_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += fac * (*f)(vecAtQPs[iq], gradAtQPs[iq]) * uhAtQP[iq]; + } + + + // ========== VecAndGradVecAtQP_ZOT ========== + + VecAndGradVecAtQP_ZOT::VecAndGradVecAtQP_ZOT(DOFVectorBase<double> *dv, + DOFVectorBase<double> *dGrd, + BinaryAbstractFunction<double, double, WorldVector<double> > *af) + : ZeroOrderTerm(af->getDegree()), vec(dv), vecGrd(dGrd), f(af) + { + TEST_EXIT(dv)("No vector!\n"); + TEST_EXIT(dGrd)("No gradient vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + auxFeSpaces.insert(dGrd->getFESpace()); + } + + void VecAndGradVecAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); + gradAtQPs = getGradientsAtQPs(vecGrd, elInfo, subAssembler, quad); + } + + void VecAndGradVecAtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) + { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += (*f)(vecAtQPs[iq], gradAtQPs[iq]); + } + + void VecAndGradVecAtQP_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += fac * (*f)(vecAtQPs[iq], gradAtQPs[iq]) * uhAtQP[iq]; + } + + + // ========== VecAndGradVec2AtQP_ZOT ========== + + VecAndGradVec2AtQP_ZOT::VecAndGradVec2AtQP_ZOT(DOFVectorBase<double> *dv, + DOFVectorBase<double> *dGrd1, + DOFVectorBase<double> *dGrd2, + TertiaryAbstractFunction<double, double, WorldVector<double>, WorldVector<double> > *af) + : ZeroOrderTerm(af->getDegree()), vec(dv), vecGrd1(dGrd1), vecGrd2(dGrd2), f(af) + { + TEST_EXIT(dv)("No vector!\n"); + TEST_EXIT(dGrd1)("No first gradient vector!\n"); + TEST_EXIT(dGrd2)("No second gradient vector!\n"); + + auxFeSpaces.insert(dv->getFESpace()); + auxFeSpaces.insert(dGrd1->getFESpace()); + auxFeSpaces.insert(dGrd2->getFESpace()); + } + + void VecAndGradVec2AtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); + grad1AtQPs = getGradientsAtQPs(vecGrd1, elInfo, subAssembler, quad); + grad2AtQPs = getGradientsAtQPs(vecGrd2, elInfo, subAssembler, quad); + } + + void VecAndGradVec2AtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) + { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += (*f)(vecAtQPs[iq], grad1AtQPs[iq], grad2AtQPs[iq]); + } + + void VecAndGradVec2AtQP_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += + fac * (*f)(vecAtQPs[iq], grad1AtQPs[iq], grad2AtQPs[iq]) * uhAtQP[iq]; + } + + + // ========== VecOfDOFVecsAtQP_ZOT ========== + + VecOfDOFVecsAtQP_ZOT::VecOfDOFVecsAtQP_ZOT(const std::vector<DOFVectorBase<double>*>& dv, + AbstractFunction<double, std::vector<double> > *af) + : ZeroOrderTerm(af->getDegree()), vecs(dv), f(af) + { + vecsAtQPs.resize(vecs.size()); + + for (int i = 0; i < static_cast<int>(dv.size()); i++) { + TEST_EXIT(dv[i])("One vector is NULL!\n"); + + auxFeSpaces.insert(dv[i]->getFESpace()); + } + } + + void VecOfDOFVecsAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + int size = static_cast<int>(vecs.size()); + for (int i = 0; i < size; i++) + vecsAtQPs[i] = getVectorAtQPs(vecs[i], elInfo, subAssembler, quad); + } + + void VecOfDOFVecsAtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) + { + int size = static_cast<int>(vecs.size()); + std::vector<double> arg(size); + + for (int iq = 0; iq < nPoints; iq++) { + for (int i = 0; i < size; i++) + arg[i] = vecsAtQPs[i][iq]; + + C[iq] += (*f)(arg); + } + } + + void VecOfDOFVecsAtQP_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + int size = static_cast<int>(vecs.size()); + std::vector<double> arg(size); + + for (int iq = 0; iq < nPoints; iq++) { + for (int i = 0; i < size; i++) + arg[i] = vecsAtQPs[i][iq]; + + result[iq] += fac * (*f)(arg) * uhAtQP[iq]; + } + } + + + // ========== VecOfGradientsAtQP_ZOT ========== + + VecOfGradientsAtQP_ZOT::VecOfGradientsAtQP_ZOT(const std::vector<DOFVectorBase<double>*>& dv, + AbstractFunction<double, std::vector<WorldVector<double>*> > *af) + : ZeroOrderTerm(af->getDegree()), vecs(dv), f(af) + { + gradsAtQPs.resize(vecs.size()); + + for (int i = 0; i < static_cast<int>(dv.size()); i++) { + TEST_EXIT(dv[i])("One vector is NULL!\n"); + + auxFeSpaces.insert(dv[i]->getFESpace()); + } + } + + void VecOfGradientsAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + int size = static_cast<int>(vecs.size()); + for (int i = 0; i < size; i++) + gradsAtQPs[i] = getGradientsAtQPs(vecs[i], elInfo, subAssembler, quad); + } + + void VecOfGradientsAtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) + { + int size = static_cast<int>(vecs.size()); + std::vector<WorldVector<double>*> arg(size); + + for (int iq = 0; iq < nPoints; iq++) { + for (int i = 0; i < size; i++) + arg[i] = &(gradsAtQPs[i][iq]); + + C[iq] += (*f)(arg); + } + } + + void VecOfGradientsAtQP_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + int size = static_cast<int>(vecs.size()); + std::vector<WorldVector<double>*> arg(size); + + for (int iq = 0; iq < nPoints; iq++) { + for (int i = 0; i < size; i++) + arg[i] = &(gradsAtQPs[i][iq]); + + result[iq] += fac * (*f)(arg) * uhAtQP[iq]; + } + } + + + // ========== VecDivergence_ZOT ========== + + VecDivergence_ZOT::VecDivergence_ZOT(int nComponents, + DOFVectorBase<double> *vec0, + DOFVectorBase<double> *vec1, + DOFVectorBase<double> *vec2) + : ZeroOrderTerm(0) + { + vecs.resize(nComponents); + gradsAtQPs.resize(nComponents); + vecs[0] = vec0; + vecs[1] = vec1; + vecs[2] = vec2; + + auxFeSpaces.insert(vec0->getFESpace()); + if (vec1) + auxFeSpaces.insert(vec1->getFESpace()); + if (vec2) + auxFeSpaces.insert(vec2->getFESpace()); + } + + void VecDivergence_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + int size = static_cast<int>(vecs.size()); + for (int i = 0; i < size; i++) + gradsAtQPs[i] = getGradientsAtQPs(vecs[i], elInfo, subAssembler, quad); + } + + + void VecDivergence_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) + { + int size = static_cast<int>(vecs.size()); + + for (int iq = 0; iq < nPoints; iq++) + for (int i = 0; i < size; i++) + C[iq] += gradsAtQPs[i][iq][i]; + } + + void VecDivergence_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + int size = static_cast<int>(vecs.size()); + + for (int iq = 0; iq < nPoints; iq++) { + double d = 0.0; + for (int i = 0; i < size; i++) + d += gradsAtQPs[i][iq][i]; + + result[iq] += d * uhAtQP[iq] * fac; + } + } + + + // ========== VecAndVecOfGradientsAtQP_ZOT ========= + + VecAndVecOfGradientsAtQP_ZOT::VecAndVecOfGradientsAtQP_ZOT(DOFVector<double> *v, + const std::vector<DOFVector<double>*>& dv, + BinaryAbstractFunction<double, double, std::vector<WorldVector<double>*> > *af) + : ZeroOrderTerm(af->getDegree()), vec(v), vecs(dv), f(af) + { + gradsAtQPs.resize(vecs.size()); + + TEST_EXIT(v)("No vector!\n"); + + auxFeSpaces.insert(v->getFESpace()); + for (int i = 0; i < static_cast<int>(dv.size()); i++) { + TEST_EXIT(dv[i])("One gradient vector is NULL!\n"); + + auxFeSpaces.insert(dv[i]->getFESpace()); + } + } + + void VecAndVecOfGradientsAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + int size = static_cast<int>(vecs.size()); + for (int i = 0; i < size; i++) + gradsAtQPs[i] = getGradientsAtQPs(vecs[i], elInfo, subAssembler, quad); + + vecAtQPs = getVectorAtQPs(vec, elInfo, subAssembler, quad); + } + + void VecAndVecOfGradientsAtQP_ZOT::getC(const ElInfo *, int nPoints, + std::vector<double> &C) + { + int size = static_cast<int>(vecs.size()); + std::vector<WorldVector<double>*> arg(size); + + for (int iq = 0; iq < nPoints; iq++) { + for (int i = 0; i < size; i++) + arg[i] = &(gradsAtQPs[i][iq]); + + C[iq] += (*f)(vecAtQPs[iq], arg); + } + } + + void VecAndVecOfGradientsAtQP_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + int size = static_cast<int>(vecs.size()); + std::vector<WorldVector<double>*> arg(size); + + for (int iq = 0; iq < nPoints; iq++) { + for (int i = 0; i < size; i++) + arg[i] = &(gradsAtQPs[i][iq]); + + result[iq] += fac * (*f)(vecAtQPs[iq], arg) * uhAtQP[iq]; + } + } + + + // ========== Vec2AndGrad2AtQP_ZOT ========== + + Vec2AndGrad2AtQP_ZOT::Vec2AndGrad2AtQP_ZOT(DOFVectorBase<double> *dv1, + DOFVectorBase<double> *dv2, + QuartAbstractFunction<double, double, double, WorldVector<double>,WorldVector<double> > *af) + : ZeroOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), f(af) + { + TEST_EXIT(dv1)("No first vector!\n"); + TEST_EXIT(dv2)("No second vector!\n"); + + auxFeSpaces.insert(dv1->getFESpace()); + auxFeSpaces.insert(dv2->getFESpace()); + } + + void Vec2AndGrad2AtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vecAtQPs1 = getVectorAtQPs(vec1, elInfo, subAssembler, quad); + vecAtQPs2 = getVectorAtQPs(vec2, elInfo, subAssembler, quad); + gradAtQPs1 = getGradientsAtQPs(vec1, elInfo, subAssembler, quad); + gradAtQPs2 = getGradientsAtQPs(vec2, elInfo, subAssembler, quad); + } + + + void Vec2AndGrad2AtQP_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += + fac * (*f)(vecAtQPs1[iq], vecAtQPs2[iq], gradAtQPs1[iq], gradAtQPs2[iq]) * + uhAtQP[iq]; + } + + void Vec2AndGrad2AtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) + { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += (*f)(vecAtQPs1[iq], vecAtQPs2[iq], gradAtQPs1[iq], gradAtQPs2[iq]); + } + + + // ========== Vec2AndGradVecAtQP_ZOT ========== + + Vec2AndGradVecAtQP_ZOT::Vec2AndGradVecAtQP_ZOT(DOFVectorBase<double> *dv1, + DOFVectorBase<double> *dv2, + DOFVectorBase<double> *dGrd, + TertiaryAbstractFunction<double, double,double, WorldVector<double> > *af) + : ZeroOrderTerm(af->getDegree()), vec1(dv1), vec2(dv2), vecGrd(dGrd), f(af) + { + TEST_EXIT(dv1)("No vector!\n"); + TEST_EXIT(dv2)("No vector!\n"); + TEST_EXIT(dGrd)("No gradient vector!\n"); + + auxFeSpaces.insert(dv1->getFESpace()); + auxFeSpaces.insert(dv2->getFESpace()); + auxFeSpaces.insert(dGrd->getFESpace()); + } + + void Vec2AndGradVecAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + vec1AtQPs = getVectorAtQPs(vec1, elInfo, subAssembler, quad); + vec2AtQPs = getVectorAtQPs(vec2, elInfo, subAssembler, quad); + gradAtQPs = getGradientsAtQPs(vecGrd, elInfo, subAssembler, quad); + } + + void Vec2AndGradVecAtQP_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) + { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += (*f)(vec1AtQPs[iq], vec2AtQPs[iq], gradAtQPs[iq]); + } + + void Vec2AndGradVecAtQP_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += + fac * (*f)(vec1AtQPs[iq], vec2AtQPs[iq], gradAtQPs[iq]) * uhAtQP[iq]; + } + + + // =========== General_ZOT ========== + + General_ZOT::General_ZOT(std::vector<DOFVectorBase<double>*> vecs, + std::vector<DOFVectorBase<double>*> grads, + TertiaryAbstractFunction<double, WorldVector<double>, std::vector<double>, std::vector<WorldVector<double> > > *af) + : ZeroOrderTerm(af->getDegree()), vecs_(vecs), grads_(grads), f_(af) + { + vecsAtQPs_.resize(vecs_.size()); + gradsAtQPs_.resize(grads_.size()); + + for (int i = 0; i < static_cast<int>(vecs.size()); i++) { + TEST_EXIT(vecs[i])("One vector is NULL!\n"); + + auxFeSpaces.insert(vecs[i]->getFESpace()); + } + + for (int i = 0; i < static_cast<int>(grads.size()); i++) { + TEST_EXIT(grads[i])("One gradient vector is NULL!\n"); + + auxFeSpaces.insert(grads[i]->getFESpace()); + } + + vecsArg.resize(vecs_.size()); + gradsArg.resize(grads_.size()); + } + + void General_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad) + { + int nVecs = static_cast<int>(vecs_.size()); + int nGrads = static_cast<int>(grads_.size()); + + coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); + + for (int i = 0; i < nVecs; i++) + vecsAtQPs_[i] = getVectorAtQPs(vecs_[i], elInfo, subAssembler, quad); + for (int i = 0; i < nGrads; i++) + gradsAtQPs_[i] = getGradientsAtQPs(grads_[i], elInfo, subAssembler, quad); + } + + void General_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) + { + unsigned int nVecs = vecs_.size(); + unsigned int nGrads = grads_.size(); + + for (int iq = 0; iq < nPoints; iq++) { + for (unsigned int i = 0; i < nVecs; i++) + vecsArg[i] = vecsAtQPs_[i][iq]; + for (unsigned int i = 0; i < nGrads; i++) + gradsArg[i] = gradsAtQPs_[i][iq]; + + C[iq] += (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg); + } + } + + void General_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + unsigned int nVecs = vecs_.size(); + unsigned int nGrads = grads_.size(); + + for (int iq = 0; iq < nPoints; iq++) { + for (unsigned int i = 0; i < nVecs; i++) + vecsArg[i] = vecsAtQPs_[i][iq]; + for (unsigned int i = 0; i < nGrads; i++) + gradsArg[i] = gradsAtQPs_[i][iq]; + + result[iq] += fac * (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg) * uhAtQP[iq]; + } + } + + + // ========== GeneralParametric_ZOT ========== + + GeneralParametric_ZOT::GeneralParametric_ZOT(std::vector<DOFVectorBase<double>*> vecs, + std::vector<DOFVectorBase<double>*> grads, + QuartAbstractFunction<double, + WorldVector<double>, + WorldVector<double>, + std::vector<double>, + std::vector<WorldVector<double> > > *af) + : ZeroOrderTerm(af->getDegree()), vecs_(vecs), grads_(grads), f_(af) + { + vecsAtQPs_.resize(vecs_.size()); + gradsAtQPs_.resize(grads_.size()); + + for (int i = 0; i < static_cast<int>(vecs.size()); i++) { + TEST_EXIT(vecs[i])("One vector is NULL!\n"); + + auxFeSpaces.insert(vecs[i]->getFESpace()); + } + + for (int i = 0; i < static_cast<int>(grads.size()); i++) { + TEST_EXIT(grads[i])("One gradient vector is NULL!\n"); + + auxFeSpaces.insert(grads[i]->getFESpace()); + } + } + + void GeneralParametric_ZOT::initElement(const ElInfo* elInfo, SubAssembler* + subAssembler, Quadrature *quad) + { + int nVecs = static_cast<int>(vecs_.size()); + int nGrads = static_cast<int>(grads_.size()); + + elInfo->getElementNormal(elementNormal_); + coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); + + for (int i = 0; i < nVecs; i++) + vecsAtQPs_[i] = getVectorAtQPs(vecs_[i], elInfo, subAssembler, quad); + for (int i = 0; i < nGrads; i++) + gradsAtQPs_[i] = getGradientsAtQPs(grads_[i], elInfo, subAssembler, quad); + } + + void GeneralParametric_ZOT::getC(const ElInfo *, int nPoints, std::vector<double> &C) + { + int nVecs = static_cast<int>(vecs_.size()); + int nGrads = static_cast<int>(grads_.size()); + + std::vector<double> vecsArg(nVecs); + std::vector<WorldVector<double> > gradsArg(nGrads); + + for (int iq = 0; iq < nPoints; iq++) { + for (int i = 0; i < nVecs; i++) + vecsArg[i] = vecsAtQPs_[i][iq]; + for (int i = 0; i < nGrads; i++) + gradsArg[i] = gradsAtQPs_[i][iq]; + + C[iq] += (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg); + } + } + + void GeneralParametric_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + int nVecs = static_cast<int>(vecs_.size()); + int nGrads = static_cast<int>(grads_.size()); + + std::vector<double> vecsArg(nVecs); + std::vector<WorldVector<double> > gradsArg(nGrads); + + for (int iq = 0; iq < nPoints; iq++) { + for (int i = 0; i < nVecs; i++) + vecsArg[i] = vecsAtQPs_[i][iq]; + for (int i = 0; i < nGrads; i++) + gradsArg[i] = gradsAtQPs_[i][iq]; + result[iq] += + fac * (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg) * uhAtQP[iq]; + } + } + + + // ========== CoordsAtQP_ZOT ========== + + void CoordsAtQP_ZOT::initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad) + { + coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); + } + + void CoordsAtQP_ZOT::getC(const ElInfo *elInfo, int nPoints, std::vector<double> &C) + { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += (*g)(coordsAtQPs[iq]); + } + + void CoordsAtQP_ZOT::eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac) + { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += fac * (*g)(coordsAtQPs[iq]) * uhAtQP[iq]; + } + + +} diff --git a/AMDiS/src/ZeroOrderTerm.h b/AMDiS/src/ZeroOrderTerm.h new file mode 100644 index 00000000..01e89cda --- /dev/null +++ b/AMDiS/src/ZeroOrderTerm.h @@ -0,0 +1,959 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// ============================================================================ +// == == +// == TU Dresden == +// == == +// == Institut f�r Wissenschaftliches Rechnen == +// == Zellescher Weg 12-14 == +// == 01069 Dresden == +// == germany == +// == == +// ============================================================================ +// == == +// == https://gforge.zih.tu-dresden.de/projects/amdis/ == +// == == +// ============================================================================ + +/** \file ZeroOrderTerm.h */ + +#ifndef AMDIS_ZERO_ORDER_TERM_H +#define AMDIS_ZERO_ORDER_TERM_H + +#include "AMDiS_fwd.h" +#include "OperatorTerm.h" +#include "AbstractFunction.h" + +namespace AMDiS { + + /** + * \ingroup Assembler + * + * \brief + * Describes zero order terms: \f$ cu(\vec{x}) \f$. + */ + class ZeroOrderTerm : public OperatorTerm + { + public: + /// Constructor. + ZeroOrderTerm(int deg) : OperatorTerm(deg) {} + + /// Destructor. + virtual ~ZeroOrderTerm() {} + + /// Evaluates \f$ c \f$ + virtual void getC(const ElInfo *elInfo, int nPoints, + std::vector<double> &C) = 0; + + }; + + + /** + * \ingroup Assembler + * + * \brief + * Simple zero order term + */ + class Simple_ZOT : public ZeroOrderTerm + { + public: + /// Constructor. + Simple_ZOT(double f = 1.0) : ZeroOrderTerm(0), factor(f) {} + + /// Implements ZeroOrderTerm::getC(). + inline void getC(const ElInfo *, int nPoints, std::vector<double> &C) + { + for (int iq = 0; iq < nPoints; iq++) + C[iq] += factor; + } + + /// Implements ZeroOrderTerm::eval(). + inline void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *, + const WorldMatrix<double> *, + double *result, + double fac) + { + for (int iq = 0; iq < nPoints; iq++) + result[iq] += fac * factor * uhAtQP[iq]; + } + + protected: + /// Constant factor of zero order term. + double factor; + }; + + + /** + * \ingroup Assembler + * + * \brief + * Zero order term: \f$ f(v(\vec{x})) u(\vec{x})\f$ + */ + class VecAtQP_ZOT : public ZeroOrderTerm + { + public: + /// Constructor. + VecAtQP_ZOT(DOFVectorBase<double> *dv, + AbstractFunction<double, double> *ab); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implementation of \ref OperatorTerm::initElement() for multilpe meshes. + void initElement(const ElInfo* smallElInfo, + const ElInfo* largeElInfo, + SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements ZeroOrderTerm::getC(). + void getC(const ElInfo *, int nPoints, std::vector<double> &C); + + /// Implements ZeroOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + /// DOFVector to be evaluated at quadrature points. + DOFVectorBase<double>* vec; + + /// Vector v at quadrature points. + double *vecAtQPs; + + /// Function for c. + AbstractFunction<double, double> *f; + }; + + + /** + * \ingroup Assembler + * + * \brief + * Zero order term: \f$ f(v(\vec{x})) g(w(\vec{x})) u(\vec{x})\f$ + */ + class MultVecAtQP_ZOT : public ZeroOrderTerm + { + public: + /// Constructor. + MultVecAtQP_ZOT(DOFVectorBase<double> *dv1, + DOFVectorBase<double> *dv2, + AbstractFunction<double, double> *f1, + AbstractFunction<double, double> *f2); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements ZeroOrderTerm::getC(). + void getC(const ElInfo *, int nPoints, std::vector<double> &C); + + /// Implements ZeroOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + /// DOFVectorBase to be evaluated at quadrature points. + DOFVectorBase<double>* vec1; + DOFVectorBase<double>* vec2; + + /// Vector v at quadrature points. + double *vecAtQPs1; + double *vecAtQPs2; + + /// Function for c. + AbstractFunction<double, double> *f1; + AbstractFunction<double, double> *f2; + }; + + + /** + * \ingroup Assembler + * + * \brief + * Zero order term: \f$ f(v(\vec{x}), w(\vec{x})) u(\vec{x})\f$ + */ + class Vec2AtQP_ZOT : public ZeroOrderTerm + { + public: + /// Constructor. + Vec2AtQP_ZOT(DOFVectorBase<double> *dv1, + DOFVectorBase<double> *dv2, + BinaryAbstractFunction<double, double, double> *f); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implementation of \ref OperatorTerm::initElement() for multilpe meshes. + void initElement(const ElInfo* smallElInfo, + const ElInfo* largeElInfo, + SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements ZeroOrderTerm::getC(). + void getC(const ElInfo *, int nPoints, std::vector<double> &C); + + /// Implements ZeroOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + /// First DOFVector to be evaluated at quadrature points. + DOFVectorBase<double>* vec1; + /// Second DOFVector to be evaluated at quadrature points. + DOFVectorBase<double>* vec2; + + /// Values of the first DOFVector at the quadrature points. + double *vecAtQPs1; + /// Values of the second DOFVector at the quadrature points. + double *vecAtQPs2; + + /// Function for c. + BinaryAbstractFunction<double, double, double> *f; + }; + + + /** + * \ingroup Assembler + * + * \brief + * Zero order term: \f$ f(v(\vec{x}), w(\vec{x})) u(\vec{x})\f$ + */ + class Vec3AtQP_ZOT : public ZeroOrderTerm + { + public: + /// Constructor. + Vec3AtQP_ZOT(DOFVectorBase<double> *dv1, + DOFVectorBase<double> *dv2, + DOFVectorBase<double> *dv3, + TertiaryAbstractFunction<double, double, double, double> *f); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements ZeroOrderTerm::getC(). + void getC(const ElInfo *, int nPoints, std::vector<double> &C); + + /// Implements ZeroOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + /// DOFVectors to be evaluated at quadrature points. + DOFVectorBase<double> *vec1, *vec2, *vec3; + + /// Vectors at quadrature points. + double *vecAtQPs1, *vecAtQPs2, *vecAtQPs3; + + /// Function for c. + TertiaryAbstractFunction<double, double, double, double> *f; + }; + + + /** + * \ingroup Assembler + * + * \brief + * + */ + class FctGradientCoords_ZOT : public ZeroOrderTerm + { + public: + /// Constructor. + FctGradientCoords_ZOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<double, WorldVector<double>, WorldVector<double> > *f); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements SecondOrderTerm::getC(). + void getC(const ElInfo *elInfo, int nPoints, std::vector<double> &C); + + /// Implements ZeroOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + DOFVectorBase<double>* vec; + + /// Function wich maps \ref gradAtQPs to a double. + BinaryAbstractFunction<double, WorldVector<double>, WorldVector<double> > *f; + + /** \brief + * Pointer to a WorldVector<double> array containing the gradients of the DOFVector + * at each quadrature point. + */ + WorldVector<double>* gradAtQPs; + + WorldVector<double>* coordsAtQPs; + + }; + + /** + * \ingroup Assembler + * + * \brief + */ + class VecGradCoordsAtQP_ZOT : public ZeroOrderTerm + { + public: + /// Constructor. + VecGradCoordsAtQP_ZOT(DOFVectorBase<double> *dv, + TertiaryAbstractFunction<double, double, WorldVector<double>, WorldVector<double> > *f); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements ZeroOrderTerm::getC(). + void getC(const ElInfo *, int nPoints, std::vector<double> &C); + + /// Implements ZeroOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + /// DOFVector to be evaluated at quadrature points. + DOFVectorBase<double>* vec; + + /// Vector v at quadrature points. + double *vecAtQPs; + + /// Gradient at quadrature points. + WorldVector<double>* gradAtQPs; + + WorldVector<double>* coordsAtQPs; + + /// Function for c. + TertiaryAbstractFunction<double, double, WorldVector<double>, WorldVector<double> > *f; + }; + + /** + * \ingroup Assembler + * + * \brief + */ + class VecAndCoordsAtQP_ZOT : public ZeroOrderTerm + { + public: + /// Constructor. + VecAndCoordsAtQP_ZOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<double, double, WorldVector<double> > *f); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements ZeroOrderTerm::getC(). + void getC(const ElInfo *, int nPoints, std::vector<double> &C); + + /// Implements ZeroOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + /// DOFVector to be evaluated at quadrature points. + DOFVectorBase<double>* vec; + + /// Vector v at quadrature points. + double *vecAtQPs; + + /// Gradient at quadrature points. + WorldVector<double>* coordsAtQPs; + + /// Function for c. + BinaryAbstractFunction<double, double, WorldVector<double> > *f; + }; + + + /** + * \ingroup Assembler + * + * \brief + */ + class Vec2AndGradAtQP_ZOT : public ZeroOrderTerm + { + public: + /// Constructor. + Vec2AndGradAtQP_ZOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, + TertiaryAbstractFunction<double, double, WorldVector<double>, double > *af); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements ZeroOrderTerm::getC(). + void getC(const ElInfo *, int nPoints, std::vector<double> &C); + + /// Implements ZeroOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + /// DOFVector to be evaluated at quadrature points. + DOFVectorBase<double>* vec1; + DOFVectorBase<double>* vec2; + + /// Vector v at quadrature points. + double *vecAtQPs1; + double *vecAtQPs2; + + /// Gradient at quadrature points. + WorldVector<double> *gradAtQPs; + + /// Function for c. + TertiaryAbstractFunction<double, double, WorldVector<double>, double > *f; + }; + + + /** + * \ingroup Assembler + * + * \brief + * + */ + class FctGradient_ZOT : public ZeroOrderTerm + { + public: + /// Constructor. + FctGradient_ZOT(DOFVectorBase<double> *dv, + AbstractFunction<double, WorldVector<double> > *f); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements SecondOrderTerm::getC(). + void getC(const ElInfo *elInfo, int nPoints, std::vector<double> &C); + + /// Implements ZeroOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + DOFVectorBase<double>* vec; + + /// Function wich maps \ref gradAtQPs to a double. + AbstractFunction<double, WorldVector<double> > *f; + + /** \brief + * Pointer to a WorldVector<double> array containing the gradients of the DOFVector + * at each quadrature point. + */ + WorldVector<double>* gradAtQPs; + + }; + + + /** + * \ingroup Assembler + * + * \brief + */ + class VecAndGradAtQP_ZOT : public ZeroOrderTerm + { + public: + /// Constructor. + VecAndGradAtQP_ZOT(DOFVectorBase<double> *dv, + BinaryAbstractFunction<double, double, WorldVector<double> > *f); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements ZeroOrderTerm::getC(). + void getC(const ElInfo *, int nPoints, std::vector<double> &C); + + /// Implements ZeroOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + /// DOFVector to be evaluated at quadrature points. + DOFVectorBase<double>* vec; + + /// Vector v at quadrature points. + double *vecAtQPs; + + /// Gradient at quadrature points. + WorldVector<double> *gradAtQPs; + + /// Function for c. + BinaryAbstractFunction<double, double, WorldVector<double> > *f; + }; + + + class VecAndGradVecAtQP_ZOT : public ZeroOrderTerm + { + public: + /// Constructor. + VecAndGradVecAtQP_ZOT(DOFVectorBase<double> *dv, + DOFVectorBase<double> *dGrd, + BinaryAbstractFunction<double, double, WorldVector<double> > *f); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements ZeroOrderTerm::getC(). + void getC(const ElInfo *, int nPoints, std::vector<double> &C); + + /// Implements ZeroOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + /// DOFVector to be evaluated at quadrature points. + DOFVectorBase<double>* vec; + + /// Vector v at quadrature points. + double *vecAtQPs; + + /// First DOFVector whose gradient is evaluated at quadrature points. + DOFVectorBase<double>* vecGrd; + + /// Gradient of first vector at quadrature points. + WorldVector<double> *gradAtQPs; + + /// Function for c. + BinaryAbstractFunction<double, double, WorldVector<double> > *f; + }; + + + class VecAndGradVec2AtQP_ZOT : public ZeroOrderTerm + { + public: + /// Constructor. + VecAndGradVec2AtQP_ZOT(DOFVectorBase<double> *dv, + DOFVectorBase<double> *dGrd1, + DOFVectorBase<double> *dGrd2, + TertiaryAbstractFunction<double, double, WorldVector<double>, WorldVector<double> > *af); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements ZeroOrderTerm::getC(). + void getC(const ElInfo *, int nPoints, std::vector<double> &C); + + /// Implements ZeroOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + /// DOFVector to be evaluated at quadrature points. + DOFVectorBase<double>* vec; + + /// Vector v at quadrature points. + double *vecAtQPs; + + /// First DOFVector whose gradient is evaluated at quadrature points. + DOFVectorBase<double>* vecGrd1; + + /// Gradient of first vector at quadrature points. + WorldVector<double> *grad1AtQPs; + + /// Second DOFVector whose gradient is evaluated at quadrature points. + DOFVectorBase<double>* vecGrd2; + + /// Gradient of second vector at quadrature points. + WorldVector<double> *grad2AtQPs; + + /// Function for c. + TertiaryAbstractFunction<double, double, WorldVector<double>, WorldVector<double> > *f; + }; + + + class VecOfDOFVecsAtQP_ZOT : public ZeroOrderTerm + { + public: + /// Constructor. + VecOfDOFVecsAtQP_ZOT(const std::vector<DOFVectorBase<double>*>& dv, + AbstractFunction<double, std::vector<double> > *f); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements ZeroOrderTerm::getC(). + void getC(const ElInfo *, int nPoints, std::vector<double> &C); + + /// Implements ZeroOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + /// Vector of DOFVectors to be evaluated at quadrature points. + std::vector<DOFVectorBase<double>*> vecs; + + /// Vectors at quadrature points. + std::vector<double*> vecsAtQPs; + + /// Function for c. + AbstractFunction<double, std::vector<double> > *f; + }; + + + class VecOfGradientsAtQP_ZOT : public ZeroOrderTerm + { + public: + /// Constructor. + VecOfGradientsAtQP_ZOT(const std::vector<DOFVectorBase<double>*>& dv, + AbstractFunction<double, std::vector<WorldVector<double>*> > *af); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements ZeroOrderTerm::getC(). + void getC(const ElInfo *, int nPoints, std::vector<double> &C); + + /// Implements ZeroOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + /// Vector of DOFVectors to be evaluated at quadrature points. + std::vector<DOFVectorBase<double>*> vecs; + + /// Vectors at quadrature points. + std::vector<WorldVector<double>*> gradsAtQPs; + + /// Function for c. + AbstractFunction<double, std::vector<WorldVector<double>*> > *f; + }; + + + class VecDivergence_ZOT : public ZeroOrderTerm + { + public: + /// Constructor. + VecDivergence_ZOT(int nComponents, + DOFVectorBase<double> *vec0, + DOFVectorBase<double> *vec1 = NULL, + DOFVectorBase<double> *vec2 = NULL); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements ZeroOrderTerm::getC(). + void getC(const ElInfo *, int nPoints, std::vector<double> &C); + + /// Implements ZeroOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + /// Vector of DOFVectors to be evaluated at quadrature points. + std::vector<DOFVectorBase<double>*> vecs; + + /// Vectors at quadrature points. + std::vector<WorldVector<double>*> gradsAtQPs; + }; + + + class VecAndVecOfGradientsAtQP_ZOT : public ZeroOrderTerm + { + public: + /// Constructor. + VecAndVecOfGradientsAtQP_ZOT(DOFVector<double> *v, + const std::vector<DOFVector<double>*>& dv, + BinaryAbstractFunction<double, double, std::vector<WorldVector<double>*> > *af); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements ZeroOrderTerm::getC(). + void getC(const ElInfo *, int nPoints, std::vector<double> &C); + + /// Implements ZeroOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + /// DOFVector to be evaluated at quadrature points. + DOFVector<double>* vec; + + /// Vector v at quadrature points. + double *vecAtQPs; + + /// Vector of DOFVectors to be evaluated at quadrature points. + std::vector<DOFVector<double>*> vecs; + + /// Vectors at quadrature points. + std::vector<WorldVector<double>*> gradsAtQPs; + + /// Function for c. + BinaryAbstractFunction<double, double, std::vector<WorldVector<double>*> > *f; + }; + + + class Vec2AndGrad2AtQP_ZOT : public ZeroOrderTerm + { + public: + Vec2AndGrad2AtQP_ZOT(DOFVectorBase<double> *dv1, + DOFVectorBase<double> *dv2, + QuartAbstractFunction<double, double, double, WorldVector<double>, WorldVector<double> > *af); + + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + void getC(const ElInfo *, int nPoints, std::vector<double> &C); + + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + DOFVectorBase<double> *vec1, *vec2; + + double *vecAtQPs1, *vecAtQPs2; + + WorldVector<double> *gradAtQPs1, *gradAtQPs2; + + QuartAbstractFunction<double, double, double, WorldVector<double>,WorldVector<double> > *f; + }; + + + class Vec2AndGradVecAtQP_ZOT : public ZeroOrderTerm + { + public: + Vec2AndGradVecAtQP_ZOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2, + DOFVectorBase<double> *dGrd, + TertiaryAbstractFunction<double, double, double, WorldVector<double> > *f); + + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + void getC(const ElInfo *, int nPoints, std::vector<double> &C); + + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + DOFVectorBase<double>* vec1; + DOFVectorBase<double>* vec2; + + double *vec1AtQPs; + double *vec2AtQPs; + + DOFVectorBase<double>* vecGrd; + WorldVector<double> *gradAtQPs; + + TertiaryAbstractFunction<double, double, double, WorldVector<double> > *f; + }; + + + class General_ZOT : public ZeroOrderTerm + { + public: + /// Constructor. + General_ZOT(std::vector<DOFVectorBase<double>*> vecs, + std::vector<DOFVectorBase<double>*> grads, + TertiaryAbstractFunction<double, WorldVector<double>, std::vector<double>, std::vector<WorldVector<double> > > *f); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements ZeroOrderTerm::getC(). + void getC(const ElInfo *, int nPoints, std::vector<double> &C); + + /// Implements ZeroOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + std::vector<DOFVectorBase<double>*> vecs_; + + std::vector<DOFVectorBase<double>*> grads_; + + TertiaryAbstractFunction<double, + WorldVector<double>, + std::vector<double>, + std::vector<WorldVector<double> > > *f_; + + WorldVector<double> *coordsAtQPs_; + + std::vector<double*> vecsAtQPs_; + + std::vector<WorldVector<double>*> gradsAtQPs_; + + std::vector<double> vecsArg; + + std::vector<WorldVector<double> > gradsArg; + }; + + + class GeneralParametric_ZOT : public ZeroOrderTerm + { + public: + /// Constructor. + GeneralParametric_ZOT(std::vector<DOFVectorBase<double>*> vecs, + std::vector<DOFVectorBase<double>*> grads, + QuartAbstractFunction<double, + WorldVector<double>, + WorldVector<double>, + std::vector<double>, + std::vector<WorldVector<double> > > *f); + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements ZeroOrderTerm::getC(). + void getC(const ElInfo *, int nPoints, std::vector<double> &C); + + /// Implements ZeroOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + std::vector<DOFVectorBase<double>*> vecs_; + + std::vector<DOFVectorBase<double>*> grads_; + + QuartAbstractFunction<double, + WorldVector<double>, + WorldVector<double>, + std::vector<double>, + std::vector<WorldVector<double> > > *f_; + + WorldVector<double> *coordsAtQPs_; + + WorldVector<double> elementNormal_; + + std::vector<double*> vecsAtQPs_; + + std::vector<WorldVector<double>*> gradsAtQPs_; + }; + + + /* + * \ingroup Assembler + * + * \brief + * Zero order term: \f$ f(\vec{x}) u(\vec{x})\f$ + */ + class CoordsAtQP_ZOT : public ZeroOrderTerm + { + public: + /// Constructor. + CoordsAtQP_ZOT(AbstractFunction<double, WorldVector<double> > *af) + : ZeroOrderTerm(af->getDegree()), g(af) + {} + + /// Implementation of \ref OperatorTerm::initElement(). + void initElement(const ElInfo* elInfo, + SubAssembler* subAssembler, + Quadrature *quad = NULL); + + /// Implements ZeroOrderTerm::getC(). + void getC(const ElInfo *, int nPoints, std::vector<double> &C); + + /// Implements ZeroOrderTerm::eval(). + void eval(int nPoints, + const double *uhAtQP, + const WorldVector<double> *grdUhAtQP, + const WorldMatrix<double> *D2UhAtQP, + double *result, + double fac); + + protected: + /// Stores coordinates at quadrature points. Set in \ref initElement(). + WorldVector<double>* coordsAtQPs; + + /// Function for c. + AbstractFunction<double, WorldVector<double> > *g; + }; +} + +#endif -- GitLab