409typename AdaptiveMeshRefinement<SC,LO,GO,NO>::DomainPtr_Type
AdaptiveMeshRefinement<SC,LO,GO,NO>::globalAlgorithm(DomainPtr_Type domainP1, DomainPtr_Type domainP12, BlockMultiVectorConstPtr_Type solution,ProblemPtr_Type problem, RhsFunc_Type rhsFunc ){
410 TEUCHOS_TEST_FOR_EXCEPTION( !hasProblemType_ , std::runtime_error,
"No consideration of Problem Type. Please specify or only use: refineArea or refineUniform.");
412 solution_ = solution;
414 currentIter_ = domainsP1_.size() ;
420 comm_ = domainP1 ->getComm();
422 if(this->comm_->getRank() == 0 && currentIter_ < maxIter_){
423 std::cout <<
" -- Adaptive Mesh Refinement --" << std::endl;
424 std::cout <<
" " << std::endl;
427 maxRank_ = std::get<1>(domainP1->getMesh()->rankRange_);
430 domainsP1_.push_back(domainP1);
431 domainsP12_.push_back(domainP12);
433 domainP1_ = domainP1;
434 domainP12_ = domainP12;
438 inputMeshP1_ = Teuchos::rcp_dynamic_cast<MeshUnstr_Type>( domainP1->getMesh() ,
true);
439 inputMeshP1_->FEType_ = domainP1->getFEType();
445 MeshUnstrPtr_Type outputMesh(
new MeshUnstr_Type(domainP1->getComm(), inputMeshP1_->volumeID_));
448 domainRefined->initWithDomain(domainP1);
450 inputMeshP12_ = Teuchos::rcp_dynamic_cast<MeshUnstr_Type>( domainP12->getMesh() ,
true);
451 inputMeshP12_->FEType_ = domainP12->getFEType();
462 SurfaceElementsPtr_Type surfaceTriangleElements = inputMeshP12_->getSurfaceTriangleElements();
463 if(surfaceTriangleElements.is_null()){
465 refinementFactory.
buildSurfaceTriangleElements( inputMeshP12_->getElementsC(),inputMeshP12_->getEdgeElements(),surfaceTriangleElements, inputMeshP12_->getEdgeMap(),inputMeshP12_->getElementMap() );
466 inputMeshP12_->surfaceTriangleElements_ = surfaceTriangleElements;
467 inputMeshP1_->surfaceTriangleElements_ = surfaceTriangleElements;
469 else if(surfaceTriangleElements->numberElements() ==0){
470 refinementFactory.
buildSurfaceTriangleElements( inputMeshP12_->getElementsC(),inputMeshP12_->getEdgeElements(),inputMeshP12_->getSurfaceTriangleElements() , inputMeshP12_->getEdgeMap(),inputMeshP12_->getElementMap() );
471 inputMeshP12_->surfaceTriangleElements_ = surfaceTriangleElements;
472 inputMeshP1_->surfaceTriangleElements_ = surfaceTriangleElements;
476 if(currentIter_ == 0 && dim_ == 2){
477 inputMeshP1_->assignEdgeFlags();
478 inputMeshP12_->assignEdgeFlags();
481 bool coarsening=
false;
482 if(coarseningCycle_ > 0 && currentIter_>0){
483 if(currentIter_ % coarseningCycle_ == 0)
486 errorElementsMv_ =Teuchos::rcp(
new MultiVector_Type( domainP12_ ->getElementMap(), 1 ) );
487 errorElementsMv_->putScalar(0.);
488 if( coarsening==
true && currentIter_ < maxIter_ ){
491 errorElementsMv_ = errorEstimator.
estimateError(inputMeshP12_, inputMeshP1_, solution, rhsFunc_, domainP12->getFEType());
493 errorEstimationMv_.push_back(errorElementsMv_);
497 int k = currentIter_;
499 MeshUnstrPtrArray_Type meshUnstructuredP1(currentIter_+n);
501 for(
int i=0; i<currentIter_+1-m; i++)
502 meshUnstructuredP1[i] = Teuchos::rcp_dynamic_cast<MeshUnstr_Type>( domainsP1_[i]->getMesh() ,
true);
506 MultiVectorPtr_Type errorElements;
507 MeshUnstrPtr_Type meshUnstructuredRefined_k ;
508 MeshUnstrPtr_Type meshUnstructuredRefined_k_1;
509 MeshUnstrPtr_Type meshUnstructuredRefined_k_m_1;
510 for(
int i=0; i<m-1 ; i++){
511 meshUnstructuredRefined_k = Teuchos::rcp_dynamic_cast<MeshUnstr_Type>( domainsP1_[currentIter_-i]->getMesh() ,
true);
512 meshUnstructuredRefined_k_1 = Teuchos::rcp_dynamic_cast<MeshUnstr_Type>( domainsP1_[currentIter_-1-i]->getMesh() ,
true);
514 errorElements = errorEstimator.
determineCoarseningError(meshUnstructuredRefined_k,meshUnstructuredRefined_k_1,errorEstimationMv_[currentIter_-i],
"backwards",markingStrategy_,theta_);
516 errorEstimationMv_[currentIter_-1-i]= errorElements;
522 meshUnstructuredRefined_k_m_1 = meshUnstructuredRefined_k_1;
524 meshUnstructuredRefined_k_m_1 =Teuchos::rcp_dynamic_cast<MeshUnstr_Type>( domainsP1_[currentIter_]->getMesh() ,
true);
527 for(
int i=0; i< n; i++){
530 errorElements = errorEstimator.
determineCoarseningError(meshUnstructuredRefined_k_m_1,meshUnstructuredP1[iterC],errorEstimationMv_[iterC+1],
"backwards",markingStrategy_,theta_);
533 errorElements = errorEstimator.
determineCoarseningError(meshUnstructuredP1[iterC-1],meshUnstructuredP1[iterC],errorEstimationMv_[iterC-1],
"forwards",markingStrategy_,theta_);
535 if(iterC > errorEstimationMv_.size())
536 errorEstimationMv_.push_back(errorElements);
538 errorEstimationMv_[iterC]=errorElements;
541 errorEstimator.
markElements(errorElements,theta_,markingStrategy_, meshUnstructuredP1[iterC]);
543 refinementFactory.
refineMesh(meshUnstructuredP1[iterC],iterC, outputMesh, refinementMode_);
545 meshUnstructuredP1[iterC+1] = outputMesh;
546 outputMesh.reset(
new MeshUnstr_Type(domainP1->getComm(), inputMeshP1_->volumeID_));
549 outputMesh = meshUnstructuredP1[iterC+1];
552 else if( currentIter_ < maxIter_ ){
554 errorElementsMv_ = errorEstimator.
estimateError(inputMeshP12_, inputMeshP1_, solution, rhsFunc_, domainP12->getFEType());
556 errorEstimationMv_.push_back(errorElementsMv_);
558 errorEstimator.
markElements(errorElementsMv_,theta_,markingStrategy_, inputMeshP1_);
560 refinementFactory.
refineMesh(inputMeshP1_,currentIter_, outputMesh, refinementMode_);
565 MultiVectorPtr_Type procNumTmp = Teuchos::rcp(
new MultiVector_Type(domainP12->getElementMap() , 1 ) );
567 procNumTmp->putScalar(comm_->getRank());
568 MultiVectorConstPtr_Type vecDecompositionConst = procNumTmp;
573 MultiVectorConstPtr_Type exactSolutionP;
574 MultiVectorConstPtr_Type exportSolutionPMv;
576 if( calculatePressure_ ){
577 exportSolutionPMv = problem->getSolution()->getBlock(1);
583 calcErrorNorms(exactSolution,solution->getBlock(0), exactSolutionP);
585 if(this->exportWithParaview_ && initExporter_==
false){
588 this->
exportSolution( inputMeshP12_, problem->getSolution()->getBlock(0), errorNodesMv_, exactSolution, exportSolutionPMv, exactSolutionP);
589 if( currentIter_< maxIter_)
590 this->
exportError( inputMeshP12_, errorElementsMv_, errorH1ElementsMv_ , difH1EtaElementsMv_ , vecDecompositionConst );
594 maxErrorEl.push_back(errorElementsMv_->getMax());
595 maxErrorKn.push_back(errorNodesMv_->getMax());
596 numElements.push_back(domainP12_->getElementMap()->getMaxAllGlobalIndex()+1);
597 numElementsProc.push_back(domainP12_->getElementsC()->numberElements());
599 numNodes.push_back(domainP12_->getMapUnique()->getMaxAllGlobalIndex()+1);
601 if(currentIter_ == maxIter_){
603 exporterSol_->closeExporter();
604 exporterError_->closeExporter();
607 std::cout <<
" -- done -- " << std::endl;
609 domainRefined->setMesh(outputMesh);
611 return domainRefined;
678 MultiVectorPtr_Type errorValues = Teuchos::rcp(
new MultiVector_Type( solution_->getBlock(0)->getMap() ) );
680 errorValues->update( 1., exactSolution, -1. ,solutionP12, 0.);
683 MultiVectorConstPtr_Type errorValuesAbs = Teuchos::rcp(
new MultiVector_Type( solution_->getBlock(0)->getMap()) );
684 errorValuesAbs = errorValues;
685 errorValues->abs(errorValuesAbs);
688 errorNodesMv_ = errorValues;
692 errorH1.push_back(std::sqrt(problem_->calculateH1Norm(errorValues)));
696 MultiVectorConstPtr_Type exactSolutionTmp = Teuchos::rcp(
new MultiVector_Type( domainP12_ ->getMapUnique() ) );
697 Teuchos::ArrayRCP<double > exactSolutionTmpA = exactSolutionTmp->getDataNonConst(0);
699 MultiVectorConstPtr_Type solutionTmp = Teuchos::rcp(
new MultiVector_Type( domainP12_ ->getMapUnique() ) );
700 Teuchos::ArrayRCP<double > solutionTmpA = solutionTmp->getDataNonConst(0);
702 Teuchos::ArrayRCP<double > exactSolutionA = exactSolution->getDataNonConst(0);
704 Teuchos::ArrayRCP<double > solutionP12A = solutionP12->getDataNonConst(0);
707 for(
int i=0; i< dofs_ ; i++){
709 MultiVectorPtr_Type errorValues = Teuchos::rcp(
new MultiVector_Type( domainP12_ ->getMapUnique() ) );
710 for(
int j=0; j< solutionTmpA.size(); j++){
711 solutionTmpA[j] = solutionP12A[j*dofs_+i];
712 exactSolutionTmpA[j] = exactSolutionA[j*dofs_+i];
716 errorValues->update( 1., exactSolutionTmp, -1. ,solutionTmp, 0.);
718 MultiVectorConstPtr_Type errorValuesAbs = Teuchos::rcp(
new MultiVector_Type( domainP12_ ->getMapUnique()) );
719 errorValuesAbs = errorValues;
721 errorValues->abs(errorValuesAbs);
723 errorL2Tmp += problem_->calculateL2Norm(errorValues);
727 errorL2.push_back(std::sqrt(errorL2Tmp));
731 if(exactSolInput_ ==
true){
732 relError.push_back(std::sqrt(problem_->calculateH1Norm(errorValues)) / std::sqrt(problem_->calculateH1Norm(exactSolution)));
735 if(exactSolInput_ ==
true){
737 Teuchos::ArrayRCP<const double > errorElement = errorElementsMv_->getData(0);
738 for(
int i=0; i < errorElement.size() ; i++){
740 if(eta < errorElement[i])
743 reduceAll<int, double> (*comm_, REDUCE_MAX, eta, outArg (eta));
747 eRelError.push_back(std::sqrt(eta)/ std::sqrt(problem_->calculateH1Norm(solutionP12)));
754 errorH1ElementsMv_ = Teuchos::rcp(
new MultiVector_Type( domainP12_ ->getElementMap(), 1 ) );
755 errorH1ElementsMv_->putScalar(0.);
756 Teuchos::ArrayRCP<SC> errorH1ElementsA = errorH1ElementsMv_->getDataNonConst(0);
758 difH1EtaElementsMv_ = Teuchos::rcp(
new MultiVector_Type( domainP12_ ->getElementMap(), 1 ) );
759 difH1EtaElementsMv_->putScalar(0.);
761 if(domainP12_->getElementMap()->getMaxAllGlobalIndex()< 1500){
762 ElementsPtr_Type elements = domainP12_->getElementsC();
763 MapConstPtr_Type elementMap = domainP12_->getElementMap();
764 MapConstPtr_Type mapUnique = domainP12_->getMapUnique();
765 MapConstPtr_Type mapRep = domainP12_->getMapRepeated();
767 vec_GO_Type repIDsVec(0);
768 for(
int i=0; i<mapRep->getMaxLocalIndex()+1; i++){
769 GO gID = mapRep->getGlobalElement(i);
770 for(
int d=0; d < dofs_ ; d++)
771 repIDsVec.push_back(gID*dofs_+d);
773 Teuchos::ArrayView<GO> repIDsVecArray = Teuchos::arrayViewFromVector(repIDsVec);
775 MapPtr_Type mapRepSystem =
776 Teuchos::rcp(
new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), repIDsVecArray , 0, domainP12_->getComm()) );
778 MultiVectorPtr_Type mvValuesError = Teuchos::rcp(
new MultiVector_Type( mapRepSystem, 1 ) );
779 Teuchos::ArrayRCP< SC > mvValuesErrorA = mvValuesError->getDataNonConst(0);
781 MultiVectorPtr_Type mvValuesErrorUnique = Teuchos::rcp(
new MultiVector_Type( solution_->getBlock(0)->getMap(), 1 ) );
785 MultiVectorPtr_Type errorNodesRep = Teuchos::rcp(
new MultiVector_Type( mapRepSystem, 1 ) );
786 Teuchos::ArrayRCP< SC > errorNodesRepA = errorNodesRep->getDataNonConst(0);
787 errorNodesRep->importFromVector(errorNodesMv_,
false,
"Insert");
790 for(
int k=0; k< elementMap->getMaxAllGlobalIndex()+1; k++){
791 mvValuesError->putScalar(0.);
792 vec_GO_Type notOnMyProc(0);
793 vec_dbl_Type notOnMyProcValue(0);
794 if(elementMap->getLocalElement(k) != -1){
795 vec_int_Type nodeList = elements->getElement(elementMap->getLocalElement(k)).getVectorNodeList();
796 for(
int j=0; j< nodeList.size(); j++){
797 for(
int d=0; d < dofs_ ; d++){
798 if(mapUnique->getLocalElement(mapRep->getGlobalElement(nodeList[j])) == -1){
799 GO gID = mapRep->getGlobalElement(nodeList[j]);
800 notOnMyProc.push_back(gID*dofs_+d);
801 notOnMyProcValue.push_back(errorNodesRepA[dofs_*nodeList[j]+d]);
804 mvValuesErrorA[dofs_*nodeList[j]+d] = errorNodesRepA[dofs_*nodeList[j]+d];
808 Teuchos::ArrayView<GO> globalNodeArray = Teuchos::arrayViewFromVector( notOnMyProc);
811 MapPtr_Type mapNodeExport =
812 Teuchos::rcp(
new Map_Type(Teuchos::OrdinalTraits<GO>::invalid(), globalNodeArray, 0, domainP12_->getComm()) );
814 MultiVectorPtr_Type notMV = Teuchos::rcp(
new MultiVector_Type( mapNodeExport, 1 ) );
815 Teuchos::ArrayRCP<SC> notMVA = notMV->getDataNonConst(0);
816 for(
int i=0; i< notMVA.size(); i++)
817 notMVA[i] = notOnMyProcValue[i];
819 mvValuesErrorUnique->importFromVector(mvValuesError,
false,
"Insert");
820 mvValuesErrorUnique->importFromVector(notMV,
false,
"Insert");
822 double valueH1 = problem_->calculateH1Norm(mvValuesErrorUnique);
824 if(elementMap->getLocalElement(k) != -1){
825 errorH1ElementsA[elementMap->getLocalElement(k)]= std::sqrt(valueH1 + valueL2);
830 MultiVectorConstPtr_Type errorH1 = errorH1ElementsMv_;
832 MultiVectorConstPtr_Type errorElements = errorElementsMv_;
834 difH1EtaElementsMv_->update( 1., errorElements , -1. , errorH1, 0.);
836 if( calculatePressure_==
true && exactSolPInput_ ==
true ){
838 MultiVectorPtr_Type errorValuesP = Teuchos::rcp(
new MultiVector_Type( domainP1_->getMapUnique() ) );
841 errorValuesP->update( 1., exactSolutionP, -1. ,solution_->getBlock(1), 0.);
844 MultiVectorConstPtr_Type errorValuesPAbs = Teuchos::rcp(
new MultiVector_Type( domainP1_->getMapUnique() ) );
845 errorValuesPAbs = errorValuesP;
846 errorValuesP->abs(errorValuesPAbs);
848 errorNodesPMv_ = errorValuesP;
850 double errorL2Tmp = problem_->calculateL2Norm(errorValuesP,1);
852 errorL2P.push_back(errorL2Tmp);
896void AdaptiveMeshRefinement<SC,LO,GO,NO>::exportSolution(MeshUnstrPtr_Type mesh, MultiVectorConstPtr_Type exportSolutionMv, MultiVectorConstPtr_Type errorValues, MultiVectorConstPtr_Type exactSolutionMv,MultiVectorConstPtr_Type exportSolutionPMv,MultiVectorConstPtr_Type exactSolutionPMv){
898 std::string exporterType =
"Scalar";
900 exporterType =
"Vector";
904 exporterSol_->addVariable( exportSolutionMv,
"u_h", exporterType, dofs_, domainP12_->getMapUnique() );
905 exporterSol_->addVariable( exactSolutionMv,
"u", exporterType, dofs_, domainP12_->getMapUnique() );
906 exporterSol_->addVariable( errorValues,
"|u-u_h|", exporterType, dofs_, domainP12_->getMapUnique() );
909 if( calculatePressure_ ){
910 exporterSolP_->addVariable( exportSolutionPMv,
"p_h",
"Scalar", dofsP_, domainP1_->getMapUnique() );
912 exporterSolP_->addVariable( exactSolutionPMv,
"p",
"Scalar", dofsP_, domainP1_->getMapUnique() );
913 exporterSolP_->addVariable( errorNodesPMv_,
"|p-p_h|",
"Scalar", dofsP_, domainP1_->getMapUnique() );
915 exporterSolP_->save( (
double) currentIter_);
920 exporterSol_->reSetup(mesh);
921 exporterSol_->updateVariables(exportSolutionMv,
"u_h");
922 exporterSol_->updateVariables( exactSolutionMv,
"u" );
923 exporterSol_->updateVariables(errorValues,
"|u-u_h|");
925 if( calculatePressure_ ){
926 exporterSolP_->reSetup(domainP1_->getMesh());
927 exporterSolP_->updateVariables( exportSolutionPMv,
"p_h");
928 if(exactSolPInput_ ){
929 exporterSolP_->updateVariables( exactSolutionPMv,
"p");
930 exporterSolP_->updateVariables( errorNodesPMv_,
"|p-p_h|");
933 exporterSolP_->save( (
double) currentIter_);
937 exporterSol_->save( (
double) currentIter_);
983 vec_GO_Type globalProcs(0);
984 for (
int i=0; i<= maxRank_; i++)
985 globalProcs.push_back(i);
987 Teuchos::ArrayView<GO> globalProcArray = Teuchos::arrayViewFromVector( globalProcs);
989 vec_GO_Type localProc(0);
990 localProc.push_back(comm_->getRank());
991 Teuchos::ArrayView<GO> localProcArray = Teuchos::arrayViewFromVector( localProc);
993 MapPtr_Type mapGlobalProc =
994 Teuchos::rcp(
new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), globalProcArray, 0, comm_) );
997 MapPtr_Type mapProc =
998 Teuchos::rcp(
new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), localProcArray, 0, comm_) );
1000 MultiVectorPtr_Type exportLocalEntry = Teuchos::rcp(
new MultiVector_Type( mapProc, 1 ) );
1002 exportLocalEntry->putScalar( (LO) numElementsProc[currentIter_] );
1004 MultiVectorPtr_Type elementList= Teuchos::rcp(
new MultiVector_Type( mapGlobalProc, 1 ) );
1005 elementList->putScalar( 0 );
1006 elementList->importFromVector( exportLocalEntry,
true,
"Insert");
1008 Teuchos::ArrayRCP<const double > elementProcList = elementList->getData(0);
1010 double maxNumElementsOnProcs = numElementsProc[currentIter_];
1011 reduceAll<int, double> (*comm_, REDUCE_MAX, maxNumElementsOnProcs, outArg (maxNumElementsOnProcs));
1013 double minNumElementsOnProcs = numElementsProc[currentIter_];
1014 reduceAll<int, double> (*comm_, REDUCE_MIN, minNumElementsOnProcs, outArg (minNumElementsOnProcs));
1017 if(comm_->getRank() == 0 && writeRefinementInfo_ ==
true){
1018 cout <<
"__________________________________________________________________________________________________________ " << endl;
1019 cout <<
" " << endl;
1020 cout <<
" Summary of Mesh Refinement" << endl;
1021 cout <<
"__________________________________________________________________________________________________________ " << endl;
1022 cout <<
" " << endl;
1023 cout <<
" Marking Strategy:\t" << markingStrategy_ << endl;
1024 cout <<
" Theta:\t\t\t" << theta_ << endl;
1025 cout <<
"__________________________________________________________________________________________________________ " << endl;
1026 cout <<
" " << endl;
1027 cout <<
" Tolerance:\t\t\t" << tol_ << endl;
1028 cout <<
" Max number of Iterations:\t" << maxIter_ << endl;
1029 cout <<
" Number of Processors:\t\t\t" << maxRank_ +1 << endl;
1030 cout <<
" Number of Refinements:\t\t" << currentIter_ << endl;
1031 cout <<
"__________________________________________________________________________________________________________ " << endl;
1032 cout <<
" " << endl;
1033 cout <<
" Refinementlevel|| Elements\t|| Nodes\t|| Max. estimated error " << endl;
1034 cout <<
"__________________________________________________________________________________________________________ " << endl;
1035 for(
int i=0; i<= currentIter_; i++)
1036 cout <<
" "<< i <<
"\t\t|| " << numElements[i] <<
"\t\t|| " << numNodes[i]<<
"\t\t|| " << maxErrorEl[i]<< endl;
1037 cout <<
"__________________________________________________________________________________________________________ " << endl;
1038 cout <<
" " << endl;
1039 if(exactSolInput_ ==
true){
1040 cout <<
" Maximal error in nodes after Refinement. " << endl;
1041 for (
int i=1; i<=currentIter_ ; i++)
1042 cout <<
" "<< i <<
":\t" << maxErrorKn[i] << endl;
1043 cout <<
"__________________________________________________________________________________________________________ " << endl;
1044 cout <<
" || u-u_h ||_H1\t||\t|| u-u_h ||_L2 ||" ;
1045 if( calculatePressure_==
true && exactSolPInput_ ==
true ){
1046 cout <<
" \t|| p-p_h||_L2 " << endl;
1050 cout <<
"__________________________________________________________________________________________________________ " << endl;
1051 for (
int i=1; i<=currentIter_ ; i++){
1052 std::cout <<
" "<< i <<
":\t"<< std::setprecision(5) << std::fixed << errorH1[i]<<
"\t\t||\t" << errorL2[i] ;
1053 if( calculatePressure_==
true && exactSolPInput_ ==
true ){
1054 std::cout <<
" \t \t||\t" << std::setprecision(5) << std::fixed << errorL2P[i] << std::endl;
1060 cout <<
"__________________________________________________________________________________________________________ " << endl;
1062 cout <<
" ||u-u_h||_H1 / ||u ||_H1 \t|| eta / ||u_h ||_H1\t" << endl;
1063 cout <<
"__________________________________________________________________________________________________________ " << endl;
1064 for (
int i=1; i<=currentIter_ ; i++){
1065 cout <<
" "<< i <<
":\t" << relError[i] <<
" \t\t||\t" << eRelError[i] << endl;
1067 cout <<
"__________________________________________________________________________________________________________ " << endl;
1068 cout <<
" " << endl;
1069 cout <<
"Distribution of elements on .. " << endl;
1071 cout <<
" Max Number of Elements on Processors " << std::setprecision(0) << std::fixed << maxNumElementsOnProcs << endl;
1072 cout <<
" Min Number of Elements on Processors " << minNumElementsOnProcs << endl;
1073 cout <<
"__________________________________________________________________________________________________________ " << endl;
1074 cout <<
"__________________________________________________________________________________________________________ " << endl;
1075 cout <<
" " << endl;
1076 cout <<
"__________________________________________________________________________________________________________ " << endl;
1077 cout <<
"__________________________________________________________________________________________________________ " << endl;
1078 cout <<
" " << endl;