Liebe Gitlab-Nutzer, lieber Gitlab-Nutzer, es ist nun möglich sich mittels des ZIH-Logins/LDAP an unserem Dienst anzumelden. Ein Anmelden über dieses erzeugt ein neues Konto. Das alte Konto ist über den Reiter "Standard" erreichbar. Die Administratoren

Dear Gitlab user, it is now possible to log in to our service using the ZIH login/LDAP. Logging in via this will create a new account. The old account can be accessed via the "Standard" tab. The administrators

Commit 1b4a08a9 authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

- New preconditioner: BFGS (taken from Frank's AMDiS code)

- Umfpack breaks, if the final residual is larger than the given tolerance
parent 5eaded80
......@@ -47,8 +47,8 @@ libamdis_la_SOURCES = \
$(PARALLEL_AMDIS_SOURCES) \
$(SOURCE_DIR)/MultiGridPreconWrapper.h $(SOURCE_DIR)/MultiGridPreconWrapper.cc \
$(SOURCE_DIR)/LagrangeInterpolRestrict.h $(SOURCE_DIR)/LagrangeInterpolRestrict.cc \
$(SOURCE_DIR)/BiCGStab.h $(SOURCE_DIR)/BiCGStab.hh\
$(SOURCE_DIR)/BiCGStab2.h $(SOURCE_DIR)/BiCGStab2.hh\
$(SOURCE_DIR)/BiCGStab.h $(SOURCE_DIR)/BiCGStab.hh \
$(SOURCE_DIR)/BiCGStab2.h $(SOURCE_DIR)/BiCGStab2.hh \
$(SOURCE_DIR)/InterpolRestrictMatrix.h $(SOURCE_DIR)/InterpolRestrictMatrix.cc \
$(SOURCE_DIR)/DOFIndexed.h $(SOURCE_DIR)/DOFIndexed.cc \
$(SOURCE_DIR)/GNUPlotWriter.h $(SOURCE_DIR)/GNUPlotWriter.cc \
......@@ -113,9 +113,21 @@ $(SOURCE_DIR)/demangle.h \
$(SOURCE_DIR)/DiagonalPreconditioner.h $(SOURCE_DIR)/DiagonalPreconditioner.cc \
$(SOURCE_DIR)/ILUPreconditioner.h $(SOURCE_DIR)/ILUPreconditioner.cc \
$(SOURCE_DIR)/ILUTPreconditioner.h $(SOURCE_DIR)/ILUTPreconditioner.cc \
$(SOURCE_DIR)/DOFAdmin.h $(SOURCE_DIR)/DOFIterator.h $(SOURCE_DIR)/DOFMatrix.h $(SOURCE_DIR)/DOFVector.h $(SOURCE_DIR)/DOFVector.hh $(SOURCE_DIR)/DOFVector.cc $(SOURCE_DIR)/Element.h $(SOURCE_DIR)/ElementConnection.h \
$(SOURCE_DIR)/ElInfo.h $(SOURCE_DIR)/ElInfo1d.h $(SOURCE_DIR)/ElInfo2d.h $(SOURCE_DIR)/ElInfo3d.h $(SOURCE_DIR)/Error.h \
$(SOURCE_DIR)/Error.hh $(SOURCE_DIR)/Estimator.h $(SOURCE_DIR)/Estimator.cc $(SOURCE_DIR)/FiniteElemSpace.h $(SOURCE_DIR)/FixVec.h $(SOURCE_DIR)/FixVec.hh $(SOURCE_DIR)/FixVecConvert.h $(SOURCE_DIR)/Flag.h $(SOURCE_DIR)/Global.h \
$(SOURCE_DIR)/QN_Precond.h $(SOURCE_DIR)/QN_Precond.hh \
$(SOURCE_DIR)/BFGS_Precond.h $(SOURCE_DIR)/BFGS_Precond.cc \
$(SOURCE_DIR)/DOFAdmin.h \
$(SOURCE_DIR)/DOFIterator.h \
$(SOURCE_DIR)/DOFMatrix.h \
$(SOURCE_DIR)/DOFVector.h $(SOURCE_DIR)/DOFVector.hh $(SOURCE_DIR)/DOFVector.cc \
$(SOURCE_DIR)/Element.h $(SOURCE_DIR)/ElementConnection.h \
$(SOURCE_DIR)/ElInfo.h $(SOURCE_DIR)/ElInfo1d.h $(SOURCE_DIR)/ElInfo2d.h $(SOURCE_DIR)/ElInfo3d.h \
$(SOURCE_DIR)/Error.h $(SOURCE_DIR)/Error.hh \
$(SOURCE_DIR)/Estimator.h $(SOURCE_DIR)/Estimator.cc \
$(SOURCE_DIR)/FiniteElemSpace.h \
$(SOURCE_DIR)/FixVec.h $(SOURCE_DIR)/FixVec.hh \
$(SOURCE_DIR)/FixVecConvert.h \
$(SOURCE_DIR)/Flag.h \
$(SOURCE_DIR)/Global.h \
$(SOURCE_DIR)/GMResSolver.h \ $(SOURCE_DIR)/GMResSolver.hh \
$(SOURCE_DIR)/GMResSolver2.h \ $(SOURCE_DIR)/GMResSolver2.hh \
$(SOURCE_DIR)/TFQMR.h \ $(SOURCE_DIR)/TFQMR.hh \
......
......@@ -156,7 +156,9 @@ am__libamdis_la_SOURCES_DIST = $(PARALLEL_DIR)/ConditionalEstimator.h \
$(SOURCE_DIR)/ILUPreconditioner.h \
$(SOURCE_DIR)/ILUPreconditioner.cc \
$(SOURCE_DIR)/ILUTPreconditioner.h \
$(SOURCE_DIR)/ILUTPreconditioner.cc $(SOURCE_DIR)/DOFAdmin.h \
$(SOURCE_DIR)/ILUTPreconditioner.cc $(SOURCE_DIR)/QN_Precond.h \
$(SOURCE_DIR)/QN_Precond.hh $(SOURCE_DIR)/BFGS_Precond.h \
$(SOURCE_DIR)/BFGS_Precond.cc $(SOURCE_DIR)/DOFAdmin.h \
$(SOURCE_DIR)/DOFIterator.h $(SOURCE_DIR)/DOFMatrix.h \
$(SOURCE_DIR)/DOFVector.h $(SOURCE_DIR)/DOFVector.hh \
$(SOURCE_DIR)/DOFVector.cc $(SOURCE_DIR)/Element.h \
......@@ -258,11 +260,12 @@ am_libamdis_la_OBJECTS = $(am__objects_1) \
libamdis_la-AdaptInstationary.lo \
libamdis_la-DiagonalPreconditioner.lo \
libamdis_la-ILUPreconditioner.lo \
libamdis_la-ILUTPreconditioner.lo libamdis_la-DOFVector.lo \
libamdis_la-Estimator.lo libamdis_la-ProblemInstat.lo \
libamdis_la-ProblemNonLin.lo libamdis_la-NonLinUpdater.lo \
libamdis_la-QPsiPhi.lo libamdis_la-BasisFunction.lo \
libamdis_la-Boundary.lo libamdis_la-CoarseningManager.lo \
libamdis_la-ILUTPreconditioner.lo libamdis_la-BFGS_Precond.lo \
libamdis_la-DOFVector.lo libamdis_la-Estimator.lo \
libamdis_la-ProblemInstat.lo libamdis_la-ProblemNonLin.lo \
libamdis_la-NonLinUpdater.lo libamdis_la-QPsiPhi.lo \
libamdis_la-BasisFunction.lo libamdis_la-Boundary.lo \
libamdis_la-CoarseningManager.lo \
libamdis_la-CoarseningManager1d.lo \
libamdis_la-CoarseningManager2d.lo \
libamdis_la-CoarseningManager3d.lo libamdis_la-demangle.lo \
......@@ -460,8 +463,8 @@ libamdis_la_SOURCES = \
$(PARALLEL_AMDIS_SOURCES) \
$(SOURCE_DIR)/MultiGridPreconWrapper.h $(SOURCE_DIR)/MultiGridPreconWrapper.cc \
$(SOURCE_DIR)/LagrangeInterpolRestrict.h $(SOURCE_DIR)/LagrangeInterpolRestrict.cc \
$(SOURCE_DIR)/BiCGStab.h $(SOURCE_DIR)/BiCGStab.hh\
$(SOURCE_DIR)/BiCGStab2.h $(SOURCE_DIR)/BiCGStab2.hh\
$(SOURCE_DIR)/BiCGStab.h $(SOURCE_DIR)/BiCGStab.hh \
$(SOURCE_DIR)/BiCGStab2.h $(SOURCE_DIR)/BiCGStab2.hh \
$(SOURCE_DIR)/InterpolRestrictMatrix.h $(SOURCE_DIR)/InterpolRestrictMatrix.cc \
$(SOURCE_DIR)/DOFIndexed.h $(SOURCE_DIR)/DOFIndexed.cc \
$(SOURCE_DIR)/GNUPlotWriter.h $(SOURCE_DIR)/GNUPlotWriter.cc \
......@@ -526,9 +529,21 @@ $(SOURCE_DIR)/demangle.h \
$(SOURCE_DIR)/DiagonalPreconditioner.h $(SOURCE_DIR)/DiagonalPreconditioner.cc \
$(SOURCE_DIR)/ILUPreconditioner.h $(SOURCE_DIR)/ILUPreconditioner.cc \
$(SOURCE_DIR)/ILUTPreconditioner.h $(SOURCE_DIR)/ILUTPreconditioner.cc \
$(SOURCE_DIR)/DOFAdmin.h $(SOURCE_DIR)/DOFIterator.h $(SOURCE_DIR)/DOFMatrix.h $(SOURCE_DIR)/DOFVector.h $(SOURCE_DIR)/DOFVector.hh $(SOURCE_DIR)/DOFVector.cc $(SOURCE_DIR)/Element.h $(SOURCE_DIR)/ElementConnection.h \
$(SOURCE_DIR)/ElInfo.h $(SOURCE_DIR)/ElInfo1d.h $(SOURCE_DIR)/ElInfo2d.h $(SOURCE_DIR)/ElInfo3d.h $(SOURCE_DIR)/Error.h \
$(SOURCE_DIR)/Error.hh $(SOURCE_DIR)/Estimator.h $(SOURCE_DIR)/Estimator.cc $(SOURCE_DIR)/FiniteElemSpace.h $(SOURCE_DIR)/FixVec.h $(SOURCE_DIR)/FixVec.hh $(SOURCE_DIR)/FixVecConvert.h $(SOURCE_DIR)/Flag.h $(SOURCE_DIR)/Global.h \
$(SOURCE_DIR)/QN_Precond.h $(SOURCE_DIR)/QN_Precond.hh \
$(SOURCE_DIR)/BFGS_Precond.h $(SOURCE_DIR)/BFGS_Precond.cc \
$(SOURCE_DIR)/DOFAdmin.h \
$(SOURCE_DIR)/DOFIterator.h \
$(SOURCE_DIR)/DOFMatrix.h \
$(SOURCE_DIR)/DOFVector.h $(SOURCE_DIR)/DOFVector.hh $(SOURCE_DIR)/DOFVector.cc \
$(SOURCE_DIR)/Element.h $(SOURCE_DIR)/ElementConnection.h \
$(SOURCE_DIR)/ElInfo.h $(SOURCE_DIR)/ElInfo1d.h $(SOURCE_DIR)/ElInfo2d.h $(SOURCE_DIR)/ElInfo3d.h \
$(SOURCE_DIR)/Error.h $(SOURCE_DIR)/Error.hh \
$(SOURCE_DIR)/Estimator.h $(SOURCE_DIR)/Estimator.cc \
$(SOURCE_DIR)/FiniteElemSpace.h \
$(SOURCE_DIR)/FixVec.h $(SOURCE_DIR)/FixVec.hh \
$(SOURCE_DIR)/FixVecConvert.h \
$(SOURCE_DIR)/Flag.h \
$(SOURCE_DIR)/Global.h \
$(SOURCE_DIR)/GMResSolver.h \ $(SOURCE_DIR)/GMResSolver.hh \
$(SOURCE_DIR)/GMResSolver2.h \ $(SOURCE_DIR)/GMResSolver2.hh \
$(SOURCE_DIR)/TFQMR.h \ $(SOURCE_DIR)/TFQMR.hh \
......@@ -652,6 +667,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-AdaptInstationary.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-AdaptStationary.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Assembler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-BFGS_Precond.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-BasisFunction.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Boundary.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-BoundaryManager.Plo@am__quote@
......@@ -1140,6 +1156,13 @@ libamdis_la-ILUTPreconditioner.lo: $(SOURCE_DIR)/ILUTPreconditioner.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-ILUTPreconditioner.lo `test -f '$(SOURCE_DIR)/ILUTPreconditioner.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ILUTPreconditioner.cc
libamdis_la-BFGS_Precond.lo: $(SOURCE_DIR)/BFGS_Precond.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-BFGS_Precond.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-BFGS_Precond.Tpo" -c -o libamdis_la-BFGS_Precond.lo `test -f '$(SOURCE_DIR)/BFGS_Precond.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/BFGS_Precond.cc; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-BFGS_Precond.Tpo" "$(DEPDIR)/libamdis_la-BFGS_Precond.Plo"; else rm -f "$(DEPDIR)/libamdis_la-BFGS_Precond.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/BFGS_Precond.cc' object='libamdis_la-BFGS_Precond.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-BFGS_Precond.lo `test -f '$(SOURCE_DIR)/BFGS_Precond.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/BFGS_Precond.cc
libamdis_la-DOFVector.lo: $(SOURCE_DIR)/DOFVector.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-DOFVector.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-DOFVector.Tpo" -c -o libamdis_la-DOFVector.lo `test -f '$(SOURCE_DIR)/DOFVector.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DOFVector.cc; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-DOFVector.Tpo" "$(DEPDIR)/libamdis_la-DOFVector.Plo"; else rm -f "$(DEPDIR)/libamdis_la-DOFVector.Tpo"; exit 1; fi
......
......@@ -19,6 +19,7 @@
#include "ElementRegion_ED.h"
#include "BiCGStab.h"
#include "BiCGStab2.h"
#include "BFGS_Precond.h"
#include "BoxSmoother.h"
#include "MultiGridPreconWrapper.h"
#include "GMResSolver2.h"
......@@ -35,49 +36,36 @@ namespace AMDiS {
creator = NEW BiCGSolver<DOFVector<double> >::Creator;
addCreator("bicgstab_albert", creator);
addCreator("1", creator);
creator = NEW CGSolver<DOFVector<double> >::Creator;
addCreator("cg", creator);
addCreator("2", creator);
creator = NEW GMResSolver<DOFVector<double> >::Creator;
addCreator("gmres", creator);
addCreator("3", creator);
creator = NEW ODirSolver<DOFVector<double> >::Creator;
addCreator("odir", creator);
addCreator("4", creator);
creator = NEW OResSolver<DOFVector<double> >::Creator;
addCreator("ores", creator);
addCreator("5", creator);
// creator = NEW BiCGStab_M<DOFVector<double> >::Creator;
// addCreator("bicgstab", creator);
// addCreator("6", creator);
creator = NEW BiCGStab<DOFVector<double> >::Creator;
addCreator("bicgstab", creator);
addCreator("6", creator);
creator = NEW MultiGridWrapperScal::Creator;
addCreator("mg", creator);
addCreator("7", creator);
creator = NEW BiCGStab2<DOFVector<double> >::Creator;
addCreator("bicgstab2", creator);
addCreator("8", creator);
// creator = NEW GMResSolver2<DOFVector<double> >::Creator;
// addCreator("gmres2", creator);
// addCreator("9", creator);
// addCreator("gmres2", creator);
creator = NEW TFQMR<DOFVector<double> >::Creator;
addCreator("tfqmr", creator);
addCreator("10", creator);
}
template<>
void CreatorMap<SmootherBase<DOFMatrix,
SparseVector<double>,
......@@ -87,13 +75,12 @@ namespace AMDiS {
creator = NEW GSSmoother<DOFMatrix, SparseVector<double>, ::std::set<DegreeOfFreedom> >::Creator;
addCreator("gs", creator);
addCreator("1", creator);
creator = NEW JacobiSmoother<DOFMatrix, SparseVector<double>, ::std::set<DegreeOfFreedom> >::Creator;
addCreator("j", creator);
addCreator("2", creator);
}
template<>
void CreatorMap<PreconditionerScal>::addDefaultCreators()
{
......@@ -101,21 +88,21 @@ namespace AMDiS {
creator = NEW DiagonalPreconditioner::Creator;
addCreator("diag", creator);
addCreator("1", creator);
creator = NEW ILUPreconditioner::Creator;
addCreator("ilu", creator);
addCreator("2", creator);
creator = NEW ILUTPreconditioner::Creator;
addCreator("ilut", creator);
addCreator("3", creator);
creator = NEW BFGS_Precond::Creator;
addCreator("bfgs", creator);
creator = NEW MGPreconWrapperScal::Creator;
addCreator("mg", creator);
addCreator("4", creator);
}
template<>
void CreatorMap<NonLinSolver<DOFVector<double> > >::addDefaultCreators()
{
......@@ -123,13 +110,12 @@ namespace AMDiS {
creator = NEW Newton<DOFVector<double> >::Creator;
addCreator("newton", creator);
addCreator("1", creator);
creator = NEW NewtonS<DOFVector<double> >::Creator;
addCreator("newton_fs", creator);
addCreator("2", creator);
}
template<>
void CreatorMap<OEMSolver<SystemVector> >::addDefaultCreators()
{
......@@ -137,59 +123,44 @@ namespace AMDiS {
creator = NEW BiCGSolver<SystemVector>::Creator;
addCreator("bicgstab_albert", creator);
addCreator("1", creator);
creator = NEW CGSolver<SystemVector>::Creator;
addCreator("cg", creator);
addCreator("2", creator);
creator = NEW GMResSolver<SystemVector>::Creator;
addCreator("gmres", creator);
addCreator("3", creator);
creator = NEW ODirSolver<SystemVector>::Creator;
addCreator("odir", creator);
addCreator("4", creator);
creator = NEW OResSolver<SystemVector>::Creator;
addCreator("ores", creator);
addCreator("5", creator);
// creator = NEW BiCGStab_M<SystemVector>::Creator;
// addCreator("bicgstab", creator);
// addCreator("6", creator);
creator = NEW BiCGStab<SystemVector>::Creator;
addCreator("bicgstab", creator);
addCreator("6", creator);
creator = NEW BiCGStab2<SystemVector>::Creator;
addCreator("bicgstab2", creator);
addCreator("8", creator);
creator = NEW MultiGridWrapperVec::Creator;
addCreator("mg", creator);
addCreator("7", creator);
creator = NEW GMResSolver2<SystemVector>::Creator;
addCreator("gmres2", creator);
addCreator("9", creator);
creator = NEW TFQMR<SystemVector>::Creator;
addCreator("tfqmr", creator);
addCreator("10", creator);
creator = NEW VecSymSolver<SystemVector>::Creator;
addCreator("vecsym", creator);
addCreator("11", creator);
#ifdef HAVE_UMFPACK
creator = NEW UmfPackSolver<SystemVector>::Creator;
addCreator("umfpack", creator);
addCreator("12", creator);
#endif
}
template<>
void CreatorMap<SmootherBase<Matrix<DOFMatrix*>,
Vector<SparseVector<double>*>,
......@@ -203,20 +174,17 @@ namespace AMDiS {
Vector<SparseVector<double>*>,
Vector< ::std::set<DegreeOfFreedom>*> >::Creator;
addCreator("gs", creator);
addCreator("1", creator);
creator = NEW JacobiSmoother<Matrix<DOFMatrix*>,
Vector<SparseVector<double>*>,
Vector< ::std::set<DegreeOfFreedom>*> >::Creator;
addCreator("j", creator);
addCreator("2", creator);
creator = NEW BoxSmoother::Creator;
addCreator("box", creator);
addCreator("3", creator);
}
template<>
void CreatorMap<NonLinSolver<SystemVector> >::addDefaultCreators()
{
......@@ -224,13 +192,12 @@ namespace AMDiS {
creator = NEW Newton<SystemVector>::Creator;
addCreator("newton", creator);
addCreator("1", creator);
creator = NEW NewtonS<SystemVector>::Creator;
addCreator("newton_fs", creator);
addCreator("2", creator);
}
template<>
void CreatorMap<Estimator>::addDefaultCreators()
{
......@@ -238,13 +205,12 @@ namespace AMDiS {
creator = NEW ResidualEstimator::Creator;
addCreator("residual", creator);
addCreator("1", creator);
creator = NEW RecoveryEstimator::Creator;
addCreator("recovery", creator);
addCreator("2", creator);
}
template<>
void CreatorMap<ElementData>::addDefaultCreators()
{
......
......@@ -103,7 +103,9 @@ namespace AMDiS {
/** \brief
* Sets \ref bound.
*/
inline void setBound(DOFVector<BoundaryType> *b) { bound = b; };
inline void setBound(DOFVector<BoundaryType> *b) {
bound = b;
};
protected:
/** \brief
......
......@@ -158,7 +158,13 @@ namespace AMDiS {
matVec->matVec(NoTranspose, *p, *r);
*r += *b;
MSG("Residual: %e\n", norm(r));
this->residual = norm(r);
MSG("Residual: %e\n", this->residual);
if (this->residual < this->tolerance) {
ERROR_EXIT("UMFPACK could not solve the system!\n");
}
return(1);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment