From 52840f48269682b8df318460c93080e21a3ac6f5 Mon Sep 17 00:00:00 2001 From: Thomas Witkowski <thomas.witkowski@gmx.de> Date: Tue, 5 Jan 2010 13:02:36 +0000 Subject: [PATCH] Fixed merge with parallelization branch. --- AMDiS/bin/Makefile.am | 1 + AMDiS/bin/Makefile.in | 32 +++++--- AMDiS/src/PollutionError.cc | 148 ++++++++++++++++++++++++++++++++++++ AMDiS/src/PollutionError.h | 101 ++++++++++++++++++++++++ 4 files changed, 271 insertions(+), 11 deletions(-) create mode 100644 AMDiS/src/PollutionError.cc create mode 100644 AMDiS/src/PollutionError.h diff --git a/AMDiS/bin/Makefile.am b/AMDiS/bin/Makefile.am index 52be8ab4..222d304a 100644 --- a/AMDiS/bin/Makefile.am +++ b/AMDiS/bin/Makefile.am @@ -18,6 +18,7 @@ if USE_PARALLEL_AMDIS $(PARALLEL_DIR)/ParallelProblem.h $(PARALLEL_DIR)/ParallelProblem.cc \ $(PARALLEL_DIR)/ParMetisPartitioner.h $(PARALLEL_DIR)/ParMetisPartitioner.cc \ $(PARALLEL_DIR)/PartitionElementData.h \ + $(PARALLEL_DIR)/PollutionError.h $(PARALLEL_DIR)/PollutionError.cc PARALLEL_INCLUDES = -I$(MPI_DIR)/include -I$(PARMETIS_DIR) libamdis_la_CXXFLAGS += -DHAVE_PARALLEL_AMDIS=1 else diff --git a/AMDiS/bin/Makefile.in b/AMDiS/bin/Makefile.in index 8cb4f015..019b4cca 100644 --- a/AMDiS/bin/Makefile.in +++ b/AMDiS/bin/Makefile.in @@ -86,14 +86,14 @@ am__libamdis_la_SOURCES_DIST = $(PARALLEL_DIR)/ParallelDomainBase.h \ $(PARALLEL_DIR)/ParallelProblem.cc \ $(PARALLEL_DIR)/ParMetisPartitioner.h \ $(PARALLEL_DIR)/ParMetisPartitioner.cc \ - $(PARALLEL_DIR)/PartitionElementData.h PARALLEL_INCLUDES = \ - -I$(MPI_DIR)/include -I$(PARMETIS_DIR) \ - $(SOURCE_DIR)/DOFIndexed.h $(SOURCE_DIR)/DOFIndexed.cc \ - $(SOURCE_DIR)/GNUPlotWriter.h $(SOURCE_DIR)/GNUPlotWriter.cc \ - $(SOURCE_DIR)/VertexVector.h $(SOURCE_DIR)/VertexVector.cc \ - $(SOURCE_DIR)/PeriodicBC.h $(SOURCE_DIR)/PeriodicBC.cc \ - $(SOURCE_DIR)/Recovery.h $(SOURCE_DIR)/Recovery.cc \ - $(SOURCE_DIR)/RecoveryEstimator.h \ + $(PARALLEL_DIR)/PartitionElementData.h \ + $(PARALLEL_DIR)/PollutionError.h \ + $(PARALLEL_DIR)/PollutionError.cc $(SOURCE_DIR)/DOFIndexed.h \ + $(SOURCE_DIR)/DOFIndexed.cc $(SOURCE_DIR)/GNUPlotWriter.h \ + $(SOURCE_DIR)/GNUPlotWriter.cc $(SOURCE_DIR)/VertexVector.h \ + $(SOURCE_DIR)/VertexVector.cc $(SOURCE_DIR)/PeriodicBC.h \ + $(SOURCE_DIR)/PeriodicBC.cc $(SOURCE_DIR)/Recovery.h \ + $(SOURCE_DIR)/Recovery.cc $(SOURCE_DIR)/RecoveryEstimator.h \ $(SOURCE_DIR)/RecoveryEstimator.cc \ $(SOURCE_DIR)/ResidualEstimator.h \ $(SOURCE_DIR)/ResidualEstimator.cc $(SOURCE_DIR)/Cholesky.h \ @@ -237,6 +237,7 @@ am__libamdis_la_SOURCES_DIST = $(PARALLEL_DIR)/ParallelDomainBase.h \ @USE_PARALLEL_AMDIS_TRUE@ libamdis_la-ConditionalMarker.lo \ @USE_PARALLEL_AMDIS_TRUE@ libamdis_la-ParallelProblem.lo \ @USE_PARALLEL_AMDIS_TRUE@ libamdis_la-ParMetisPartitioner.lo \ +@USE_PARALLEL_AMDIS_TRUE@ libamdis_la-PollutionError.lo \ @USE_PARALLEL_AMDIS_TRUE@ $(am__objects_1) am_libamdis_la_OBJECTS = $(am__objects_2) libamdis_la-DOFIndexed.lo \ libamdis_la-GNUPlotWriter.lo libamdis_la-VertexVector.lo \ @@ -471,10 +472,11 @@ libamdis_la_CXXFLAGS = $(am__append_1) $(am__append_3) $(am__append_5) \ @USE_PARALLEL_AMDIS_TRUE@ $(PARALLEL_DIR)/ParMetisPartitioner.h \ @USE_PARALLEL_AMDIS_TRUE@ $(PARALLEL_DIR)/ParMetisPartitioner.cc \ @USE_PARALLEL_AMDIS_TRUE@ $(PARALLEL_DIR)/PartitionElementData.h \ -@USE_PARALLEL_AMDIS_TRUE@ PARALLEL_INCLUDES = \ -@USE_PARALLEL_AMDIS_TRUE@ -I$(MPI_DIR)/include \ -@USE_PARALLEL_AMDIS_TRUE@ -I$(PARMETIS_DIR) $(am__append_2) +@USE_PARALLEL_AMDIS_TRUE@ $(PARALLEL_DIR)/PollutionError.h \ +@USE_PARALLEL_AMDIS_TRUE@ $(PARALLEL_DIR)/PollutionError.cc \ +@USE_PARALLEL_AMDIS_TRUE@ $(am__append_2) @USE_PARALLEL_AMDIS_FALSE@PARALLEL_INCLUDES = +@USE_PARALLEL_AMDIS_TRUE@PARALLEL_INCLUDES = -I$(MPI_DIR)/include -I$(PARMETIS_DIR) TEMPLATE_INCLUDES = -I../lib/mtl4 INCLUDES = $(AMDIS_INCLUDES) $(PARALLEL_INCLUDES) $(TEMPLATE_INCLUDES) libamdis_la_SOURCES = \ @@ -784,6 +786,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Parametric.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-PeriodicBC.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-PngWriter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-PollutionError.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-PovrayWriter.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ProblemInstat.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ProblemInterpolScal.Plo@am__quote@ @@ -893,6 +896,13 @@ libamdis_la-ParMetisPartitioner.lo: $(PARALLEL_DIR)/ParMetisPartitioner.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-ParMetisPartitioner.lo `test -f '$(PARALLEL_DIR)/ParMetisPartitioner.cc' || echo '$(srcdir)/'`$(PARALLEL_DIR)/ParMetisPartitioner.cc +libamdis_la-PollutionError.lo: $(PARALLEL_DIR)/PollutionError.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-PollutionError.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-PollutionError.Tpo" -c -o libamdis_la-PollutionError.lo `test -f '$(PARALLEL_DIR)/PollutionError.cc' || echo '$(srcdir)/'`$(PARALLEL_DIR)/PollutionError.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-PollutionError.Tpo" "$(DEPDIR)/libamdis_la-PollutionError.Plo"; else rm -f "$(DEPDIR)/libamdis_la-PollutionError.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(PARALLEL_DIR)/PollutionError.cc' object='libamdis_la-PollutionError.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-PollutionError.lo `test -f '$(PARALLEL_DIR)/PollutionError.cc' || echo '$(srcdir)/'`$(PARALLEL_DIR)/PollutionError.cc + libamdis_la-DOFIndexed.lo: $(SOURCE_DIR)/DOFIndexed.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-DOFIndexed.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-DOFIndexed.Tpo" -c -o libamdis_la-DOFIndexed.lo `test -f '$(SOURCE_DIR)/DOFIndexed.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DOFIndexed.cc; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-DOFIndexed.Tpo" "$(DEPDIR)/libamdis_la-DOFIndexed.Plo"; else rm -f "$(DEPDIR)/libamdis_la-DOFIndexed.Tpo"; exit 1; fi diff --git a/AMDiS/src/PollutionError.cc b/AMDiS/src/PollutionError.cc new file mode 100644 index 00000000..9a89e587 --- /dev/null +++ b/AMDiS/src/PollutionError.cc @@ -0,0 +1,148 @@ +#include "PollutionError.h" +#include "mpi.h" + +namespace AMDiS +{ + + PollutionErrorKonvex::BoundaryTraverseStack::BoundaryTraverseStack(Mesh *mesh, + PartitionStatus ps_) + { + TraverseStack myStack; + ElInfo *swap = + myStack.traverseFirst(mesh,-1, + Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_NEIGH); + ps = ps_; + + WorldVector<double>* centerWorld; + DimVec<double> center = DimVec<double>(2, DEFAULT_VALUE, 1.0 / 3.0); + while (swap != NULL) { + if (proofConditions(swap)) { + // if conditions are true, push the midpoint to the end of the list. a better + // algorithm should use the boundary edge + centerWorld = new WorldVector<double>(); + swap->coordToWorld(center, *centerWorld); + push_back(centerWorld); + } + swap = myStack.traverseNext(swap); + } + } + + bool AMDiS::PollutionErrorKonvex::BoundaryTraverseStack::proofConditions(ElInfo *elInfo) + { + if (elInfo == NULL) + return false; + + Element *curEl = elInfo->getElement(); + PartitionElementData *ped = + static_cast<PartitionElementData*>(curEl->getElementData(PARTITION_ED)); + + TEST_EXIT_DBG(ped != NULL)("No PartitionElementData found"); + + if (ped != NULL && ped->getPartitionStatus() == OVERLAP) { + //check neighbour + int nrNeigh = curEl->getGeo(NEIGH); + for (int i = 0; i < nrNeigh; i++) { + Element* curNeigh = elInfo->getNeighbour(i); + if (curNeigh != NULL) { + ped = + static_cast<PartitionElementData*>(curNeigh->getElementData(PARTITION_ED)); + if (ped != NULL && ped->getPartitionStatus() == ps) + return true; + } + } + } + return false; + } + + PollutionErrorKonvex::PollutionErrorKonvex(std::string name, int r) + : ResidualEstimator(name,r), + center(2,DEFAULT_VALUE, 1.0 / 3.0) + { + FUNCNAME("PollutionErrorKonvexEstimator::PollutionErrorKonvexEstimator()"); + GET_PARAMETER(0, name + "->C1p", "%f", &C1p); + GET_PARAMETER(0, name + "->C2p", "%f", &C2p); + } + + void PollutionErrorKonvex::init(double timestep) + { + FUNCNAME("PollutionErrorKonvex::init"); + ResidualEstimator::init(timestep); + + // set the distance (ie. width of the overlapped area) + // approximate the overlapped area as rectangle. then set d=max(edge1, edge2) + // retrieve all elements at the boundary overlapped -> out + + bts = new BoundaryTraverseStack(mesh, IN); + } + + void PollutionErrorKonvex::estimateElement(ElInfo *elInfo) + { + FUNCNAME("PollutionErrorKonvex::estimateElement()"); + + // switch between inner and outer + // inner part --> use H_1Norm + // outer part --> use L_2Norm + + PartitionElementData* ped = + static_cast<PartitionElementData*>(elInfo->getElement()->getElementData(PARTITION_ED)); + TEST_EXIT_DBG(ped != NULL)("No partition Elementdata found"); + + PartitionStatus ps = ped->getPartitionStatus(); + TEST_EXIT_DBG(ps != UNDEFINED)("Elementstatus undefined"); + + // save old values + double C0 = ResidualEstimator::C0; + double C1 = ResidualEstimator::C1; + + if (ps == OUT) { + //outer part + ResidualEstimator::norm = L2_NORM; + ResidualEstimator::C0 *= C2p; + + //compute distance + double d = getDistance(elInfo); + ResidualEstimator::C1 *= C2p / d; + + } else { + //inner part + ResidualEstimator::norm = H1_NORM; + ResidualEstimator::C0 *= C1p; + ResidualEstimator::C1 *= C1p; + } + + ResidualEstimator::estimateElement(elInfo); + //set old values + ResidualEstimator::C0 = C0; + ResidualEstimator::C1 = C1; + } + + double PollutionErrorKonvex::getDistance(ElInfo* element) + { + if (bts==NULL) + MSG("bts is null"); + TEST_EXIT_DBG(bts!=NULL)("no bts"); + double distance = 0.0; + double curDistance = 1.0; + //get center in world coord + WorldVector<double> centerWorld; + element->coordToWorld(center,centerWorld); + + //start traversal over all Midpoints at the boundary overlap <-> in + for (BoundaryTraverseStack::iterator myIt = bts->begin(); + myIt != bts->end(); myIt++) { + curDistance = 0; + for (int i = 0;i < dim;i++) + curDistance += ((*(*myIt))[i]-centerWorld[i]) * ((*(*myIt))[i] - centerWorld[i]); + + distance = max(curDistance, distance); + } + return distance; + } + + void PollutionErrorKonvex::exit(bool output = true) + { + ResidualEstimator::exit(output); + delete bts; + } +} + diff --git a/AMDiS/src/PollutionError.h b/AMDiS/src/PollutionError.h new file mode 100644 index 00000000..5d322969 --- /dev/null +++ b/AMDiS/src/PollutionError.h @@ -0,0 +1,101 @@ +// ============================================================================ +// == == +// == 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 PollutionError.h */ + +/** \defgroup Estimator Estimator module + * @{ <img src="estimator.png"> @} + */ + +#ifndef AMDIS_POLLUTIONERROR_KONVEX_H +#define AMDIS_POLLUTIONERROR_KONVEX_H + +#include <list> +#include <time.h> +#include "ResidualEstimator.h" +#include "PartitionElementData.h" + +namespace AMDiS { + + /** \ingroup Estimator + * \brief Estimator for parallel solutions. + * + * estimates the error using following formulae + * \f$||e_h||_{1,\Omega_0}=C_1 ||u_h||_{H_1(\Omega_1)}+ + * \frac{C_2}{d^2}||u_h||_{L_2(\Omega\setminus\Omega_1}\f$ + * where \f$\Omega\f$ is the complete area of interest and \f$\Omega_1\f$ the area of + * this process with overlapping. \f$\Omega_0\$ is the area of this process without + * overlapping,\f$d\$ contains the distance + * dist(\f$\partial \Omega_0,\partial \Omega_1\f$) + */ + class PollutionErrorKonvex : public ResidualEstimator + { + public: + class Creator : public EstimatorCreator + { + public: + Creator() : EstimatorCreator() {} + + virtual ~Creator() {} + + /// Returns a new ODirSolver object. + Estimator* create() + { + return new PollutionErrorKonvex(name, row); + } + }; + + PollutionErrorKonvex(std::string name, int r); + + //sets the overlapping width for 2d-elements + virtual void init(double timestep); + + virtual void estimateElement(ElInfo *elInfo); + + virtual void exit(bool output); + + protected: + /// constant in front of the inner residual + double C1p; + + /// constant in front of the outer residual + double C2p; + + ///traverse-class for edges and there normals in 2d + class BoundaryTraverseStack: public std::list< WorldVector<double>* > + { + public: + BoundaryTraverseStack(Mesh *mesh, PartitionStatus p); + + private: + PartitionStatus ps; + bool proofConditions(ElInfo *elInfo); + }; + + /// computes the squared distance of element el to the boundary of \f$\Omega_0$\f$ + double getDistance(ElInfo* el); + + /// stack to traverse over the boundary of \f$\Omega_0$\f$ + BoundaryTraverseStack* bts; + + /// barycentric center + DimVec<double> center; + }; +} +#endif -- GitLab