Exemple #1
0
int main(int argc,char **args) {
  
  /// Init Petsc-MPI communicator
  FemusInit mpinit(argc,args,MPI_COMM_WORLD);
  
  Files files; 
        files.CheckIODirectories();
        files.RedirectCout();
	
  /// INIT MESH =================================  
  
  unsigned short nm,nr;
  nm=4;
  std::cout<<"MULTIGRID levels: "<< nm << endl;

  nr=0;
  std::cout<<"MAX_REFINEMENT levels: " << nr << endl<< endl;
  
  int tmp=nm;  nm+=nr;  nr=tmp;
  
  char *infile = new char [50];
 
  sprintf(infile,"./input/nsbenchreg.neu");
  
  //Adimensional quantity (Lref,Uref)
  double Lref = 1.;
  double Uref = 1.;
  
  MultiLevelMesh ml_msh(nm,nr,infile,"seventh",Lref,NULL);
   
  MultiLevelSolution ml_sol(&ml_msh);
   
  // generate solution vector
  ml_sol.AddSolution("U",LAGRANGE,SECOND,2);
  ml_sol.AddSolution("V",LAGRANGE,SECOND,2);
  // the pressure variable should be the last for the Schur decomposition
  ml_sol.AddSolution("P",DISCONTINOUS_POLYNOMIAL,FIRST,1);
  ml_sol.AssociatePropertyToSolution("P","Pressure");
  
  //Initialize (update Init(...) function)
  ml_sol.Initialize("All");
  
  //Set Boundary (update Dirichlet(...) function)
  ml_sol.AttachSetBoundaryConditionFunction(SetBoundaryCondition);
  ml_sol.GenerateBdc("U","Time_dependent");
  ml_sol.GenerateBdc("V");
  ml_sol.GenerateBdc("P");

  
  MultiLevelProblem ml_prob(&ml_sol);
  
  
  Parameter parameter(Lref,Uref);
  
  // Generate fluid Object (Adimensional quantities,viscosity,density,fluid-model)
  Fluid fluid(parameter,0.001,1.,"Newtonian");
  cout << "Fluid properties: " << endl;
  cout << fluid << endl;  

  // add fluid material
  ml_prob.parameters.set<Fluid>("Fluid") = fluid;
  
  
 
  //create systems
  // add the system Navier-Stokes to the MultiLevel problem
  TransientNonlinearImplicitSystem & system = ml_prob.add_system<TransientNonlinearImplicitSystem> ("Navier-Stokes");
  system.AddSolutionToSystemPDE("U");
  system.AddSolutionToSystemPDE("V");
  system.AddSolutionToSystemPDE("P");
  
  // init all the systems
  system.init();
 
  // System Navier-Stokes
  system.SetAssembleFunction(AssembleMatrixResNS);  
  system.SetMaxNumberOfLinearIterations(1);
  system.SetLinearConvergenceTolerance(1.e-8);  
  system.SetMgType(V_CYCLE);
  system.SetMaxNumberOfNonLinearIterations(15);

  // time loop parameter
  system.SetIntervalTime(0.1);
  const unsigned int n_timesteps = 20;
  const unsigned int write_interval = 1;
  
  for (unsigned time_step = 0; time_step < n_timesteps; time_step++) {
   
    // Solving Navier-Stokes system
    std::cout << std::endl;
    std::cout << " *********** Navier-Stokes ************  " << std::endl;
    ml_prob.get_system("Navier-Stokes").solve();
   
    //update Solution
    ml_prob.get_system<TransientNonlinearImplicitSystem>("Navier-Stokes").UpdateSolution();

    // print solution
    if ( !(time_step%write_interval) ) {
        
      //print solution 
      std::vector<std::string> print_vars;
      print_vars.push_back("U");
      print_vars.push_back("V");
      print_vars.push_back("P");
      
//       ml_prob.printsol_vtu_inline("biquadratic",print_vars,time_step);
      VTKWriter vtkio(&ml_sol);
      vtkio.write(files.GetOutputPath(),"biquadratic",print_vars,time_step);
    }
  
  } //end loop timestep
  

  // Destroy all the new systems
  ml_prob.clear();
   

  delete[] infile;
  return 0;
}
Exemple #2
0
int main(int argc,char **args) {

  /// Init Petsc-MPI communicator
  FemusInit mpinit(argc,args,MPI_COMM_WORLD);
  
  Files files; 
        files.CheckIODirectories();
	//files.RedirectCout();
  
  bool Vanka=0, Gmres=0, Asm=0;
  if(argc >= 2) {
    if( !strcmp("vanka",args[1])) 	Vanka=1;
    else if( !strcmp("gmres",args[1])) 	Gmres=1;
    else if( !strcmp("asm",args[1])) 	Asm=1;
    
    if(Vanka+Gmres+Asm==0) {
      cout << "wrong input arguments!" << endl;
      exit(0);
    }
  }
  else {
    cout << "No input argument set default smoother = Gmres" << endl;
    Gmres=1;
  }
  
  /// INIT MESH =================================  
  
  unsigned short nm,nr;
  nm=4;
  std::cout<<"MULTIGRID levels: "<< nm << endl;

  nr=0;
  std::cout<<"MAX_REFINEMENT levels: " << nr << endl<< endl;
  
  int tmp=nm;  nm+=nr;  nr=tmp;
  
  char *infile = new char [50];
 
  sprintf(infile,"./input/box10x10.neu");
  
  //Adimensional quantity (Lref,Uref)
  double Lref = 1.;
  double Uref = 1.;
  
  //Steadystate NonLinearMultiLevelProblem  
  //MultiLevelMesh ml_msh(nm,nr,infile,"seventh",Lref,SetRefinementFlag); 
  MultiLevelMesh ml_msh;
  ml_msh.ReadCoarseMesh(infile,"seventh",Lref);
  ml_msh.RefineMesh(nm,nr,NULL);
  
  ml_msh.EraseCoarseLevels(nm-1);
  
  MultiLevelSolution ml_sol(&ml_msh);
  
  // generate solution vector
  
  FEOrder orderPre = FIRST;
  FEOrder orderVel = FIRST;
  FEOrder orderTemp = FIRST;
  
  ml_sol.AddSolution("U", LAGRANGE, orderVel);
  ml_sol.AddSolution("V", LAGRANGE, orderVel);
  ml_sol.AddSolution("lmbd", DISCONTINOUS_POLYNOMIAL, ZERO, 0, false);
  
  // the pressure variable should be the last for the Schur decomposition
  // ml_sol.AddSolution("P",DISCONTINOUS_POLYNOMIAL,FIRST);
  ml_sol.AddSolution("P",LAGRANGE, orderPre);
  ml_sol.AssociatePropertyToSolution("P","Pressure");
 
  ml_sol.AddSolution("T",LAGRANGE,orderTemp);
  
  //Initialize (update Init(...) function)
  ml_sol.Initialize("U");
  ml_sol.Initialize("V");
  ml_sol.Initialize("P");
  ml_sol.Initialize("T");
  ml_sol.Initialize("lmbd");
  //Set Boundary (update Dirichlet(...) function)
  ml_sol.AttachSetBoundaryConditionFunction(SetBoundaryConditionCavityFlow);
  ml_sol.GenerateBdc("U");
  ml_sol.GenerateBdc("V");
  ml_sol.GenerateBdc("P");
  ml_sol.GenerateBdc("T");
  
  SetLambda(ml_sol, 0, orderVel, ELASTICITY);
  //SetLambda(ml_sol, 0, 2,"diffusion");
  
  MultiLevelProblem ml_prob(&ml_sol);
  
  // add fluid material
  Parameter parameter(Lref,Uref);
  
  // Generate fluid Object (Adimensional quantities,viscosity,density,fluid-model)
  Fluid fluid(parameter,0.001,1,"Newtonian",0.001,1.);
  cout << "Fluid properties: " << endl;
  cout << fluid << endl;
  
  ml_prob.parameters.set<Fluid>("Fluid") = fluid;
   
  
  //BEGIN Navier-Stokes Multilevel Problem
  std::cout << std::endl;
  std::cout << " *********** Navier-Stokes ************  " << std::endl;
    
  NonLinearImplicitSystem & system1 = ml_prob.add_system<NonLinearImplicitSystem> ("Navier-Stokes");
  system1.AddSolutionToSystemPDE("U");
  system1.AddSolutionToSystemPDE("V");
  system1.AddSolutionToSystemPDE("P");
  
  // Set MG Options
  system1.SetAssembleFunction(AssembleMatrixResNS);  
  system1.SetMaxNumberOfNonLinearIterations(90);
  system1.SetMaxNumberOfLinearIterations(2);
  system1.SetLinearConvergenceTolerance(1.e-10);
  system1.SetNonLinearConvergenceTolerance(1.e-10);
  system1.SetMgType(F_CYCLE);
  system1.SetNumberPreSmoothingStep(1);
  system1.SetNumberPostSmoothingStep(1);
      
  //Set Smoother Options
  if(Gmres) 		system1.SetMgSmoother(GMRES_SMOOTHER);
  else if(Asm) 		system1.SetMgSmoother(ASM_SMOOTHER);
  else if(Vanka)	system1.SetMgSmoother(VANKA_SMOOTHER);
  
  system1.init();
  //common smoother options
//   system1.AddStabilization(true);
  system1.SetSolverFineGrids(GMRES);
  system1.SetPreconditionerFineGrids(ILU_PRECOND); 
  system1.SetTolerances(1.e-12,1.e-20,1.e+50,4);
 
  system1.ClearVariablesToBeSolved();
  //system1.AddVariableToBeSolved("All");
  system1.AddVariableToBeSolved("U");
  system1.AddVariableToBeSolved("V");
  system1.AddVariableToBeSolved("P");
  //for Vanka and ASM smoothers
  system1.SetNumberOfSchurVariables(0);
  system1.SetElementBlockNumber(4);   
  //system1.SetElementBlockNumber("All",1);     
  //for Gmres smoother
  system1.SetDirichletBCsHandling(PENALTY); 
  //system1.SetDirichletBCsHandling(ELIMINATION); 
   
  // Solve Navier-Stokes system
  ml_prob.get_system("Navier-Stokes").solve();
  //END Navier-Stokes Multilevel Problem
  
  
  //BEGIN Temperature MultiLevel Problem
  std::cout << std::endl;
  std::cout << " *********** Temperature ************* " << std::endl;
    
  LinearImplicitSystem & system2 = ml_prob.add_system<LinearImplicitSystem> ("Temperature");
  system2.AddSolutionToSystemPDE("T");
  
  
  // Set MG Options
  system2.SetAssembleFunction(AssembleMatrixResT);
  system2.SetMaxNumberOfLinearIterations(6);
  system2.SetLinearConvergenceTolerance(1.e-9);  
  system2.SetMgType(V_CYCLE);
  system2.SetNumberPreSmoothingStep(1);
  system2.SetNumberPostSmoothingStep(1);
   
  //Set Smoother Options
  if(Gmres) 		system2.SetMgSmoother(GMRES_SMOOTHER);
  else if(Asm) 		system2.SetMgSmoother(ASM_SMOOTHER);
  else if(Vanka)	system2.SetMgSmoother(VANKA_SMOOTHER);
  
  system2.init(); 
  //common smoother option
  system2.SetSolverFineGrids(GMRES); 
  system2.SetTolerances(1.e-12,1.e-20,1.e+50,4);
  system2.SetPreconditionerFineGrids(ILU_PRECOND);
  //for Vanka and ASM smoothers
  system2.ClearVariablesToBeSolved();
  system2.AddVariableToBeSolved("All");
  system2.SetNumberOfSchurVariables(0);
  system2.SetElementBlockNumber(4);                
  //for Gmres smoother
  system2.SetDirichletBCsHandling(PENALTY); 
  //system2.SetDirichletBCsHandling(ELIMINATION); 
  
  
  // Solve Temperature system
  ml_prob.get_system("Temperature").solve();
  //END Temperature Multilevel Problem
    
  /// Print all solutions
  std::vector<std::string> print_vars;
  print_vars.push_back("U");
  print_vars.push_back("V");
  print_vars.push_back("P");
  print_vars.push_back("T");
       
  VTKWriter vtkio(&ml_sol);
  vtkio.write(files.GetOutputPath(),"biquadratic",print_vars);
  //vtkio.write(DEFAULT_OUTPUTDIR,"biquadratic",print_vars);
  
  GMVWriter gmvio(&ml_sol);
  gmvio.write(DEFAULT_OUTPUTDIR,"biquadratic",print_vars);
  // gmvio.write(files.GetOutputPath(),"biquadratic",print_vars);
    
  //   XDMFWriter xdmfio(ml_sol);
  //   xdmfio.write(files.GetOutputPath(),"biquadratic",print_vars);
   
  //Destroy all the new systems
  ml_prob.clear();
  
  delete [] infile;
  return 0;
}
Exemple #3
0
int main(int argc, char** args) {

    // ======= Init ========================
  // init Petsc-MPI communicator
  FemusInit mpinit(argc, args, MPI_COMM_WORLD);
  
    // ======= Files ========================
  Files files; 
        files.CheckIODirectories();
        files.RedirectCout();

    // ======= Quad Rule ========================
  std::string fe_quad_rule("seventh");
 /* "seventh" is the order of accuracy that is used in the gauss integration scheme
    In the future it is not going to be an argument of the mesh function   */
  
    // ======= Mesh ========================
  MultiLevelMesh ml_mesh;
  ml_mesh.GenerateCoarseBoxMesh(NSUB_X,NSUB_Y,0,0.,1.,0.,1.,0.,0.,QUAD9,fe_quad_rule.c_str());
  unsigned numberOfUniformLevels = 1;
  unsigned numberOfSelectiveLevels = 0;
  ml_mesh.RefineMesh(numberOfUniformLevels , numberOfUniformLevels + numberOfSelectiveLevels, NULL);
  ml_mesh.PrintInfo();

    // ======= Solution ========================
  MultiLevelSolution ml_sol(&ml_mesh);  // define the multilevel solution and attach the ml_mesh object to it

  // add variables to ml_sol
  ml_sol.AddSolution("state",   LAGRANGE, FIRST);
  ml_sol.AddSolution("control", LAGRANGE, FIRST);
  ml_sol.AddSolution("adjoint", LAGRANGE, FIRST);
  ml_sol.AddSolution("mu",      LAGRANGE, FIRST);  
  ml_sol.AddSolution("TargReg", DISCONTINUOUS_POLYNOMIAL, ZERO); //this variable is not solution of any eqn, it's just a given field
  ml_sol.AddSolution("ContReg", DISCONTINUOUS_POLYNOMIAL, ZERO); //this variable is not solution of any eqn, it's just a given field

  const unsigned int fake_time_dep_flag = 2;  //this is needed to be able to use _SolOld
  const std::string act_set_flag_name = "act_flag";
  ml_sol.AddSolution(act_set_flag_name.c_str(), LAGRANGE, FIRST,fake_time_dep_flag);               

    // ======= Problem ========================
  MultiLevelProblem ml_prob(&ml_sol);  // define the multilevel problem attach the ml_sol object to it

  ml_prob.SetQuadratureRuleAllGeomElems(fe_quad_rule);
  ml_prob.SetFilesHandler(&files);
  
    // ======= Initial values ========================
  ml_sol.Initialize("All");    // initialize all variables to zero

//   ml_sol.Initialize("All", SetInitialCondition, &ml_prob); //unfortunately if I do this it sets all to zero //I would like to do an attach function similar to the BC
  ml_sol.Initialize("state",   SetInitialCondition, &ml_prob);
  ml_sol.Initialize("control", SetInitialCondition, &ml_prob);
  ml_sol.Initialize("adjoint", SetInitialCondition, &ml_prob);
  ml_sol.Initialize("mu",      SetInitialCondition, &ml_prob);
  ml_sol.Initialize("TargReg", SetInitialCondition, &ml_prob);
  ml_sol.Initialize("ContReg", SetInitialCondition, &ml_prob);
  ml_sol.Initialize(act_set_flag_name.c_str(),  SetInitialCondition, &ml_prob);

    // ======= Boundary Conditions ========================
  ml_sol.AttachSetBoundaryConditionFunction(SetBoundaryCondition);  // attach the boundary condition function and generate boundary data

//   ml_sol.GenerateBdc("All");  //this would do it also for the non-equation-related variables
  ml_sol.GenerateBdc("state");
  ml_sol.GenerateBdc("control");
  ml_sol.GenerateBdc("adjoint");
  ml_sol.GenerateBdc("mu");  //we need this for all Pde variables to make the matrix iterations work... but this should be related to the matrix and not to the sol... The same for the initial condition

    // ======= System ========================
  NonLinearImplicitSystemWithPrimalDualActiveSetMethod& system = ml_prob.add_system < NonLinearImplicitSystemWithPrimalDualActiveSetMethod > ("OptSys");

  system.SetActiveSetFlagName(act_set_flag_name);

  //here we decide the order in the matrix!
  const std::vector < std::string > sol_matrix_pos = {"state","control","adjoint","mu"};
  for (unsigned k = 0; k < sol_matrix_pos.size(); k++)  system.AddSolutionToSystemPDE(sol_matrix_pos[k].c_str());  
  
  // attach the assembling function to system
  system.SetAssembleFunction(AssembleProblem);
  
  ml_sol.SetWriter(VTK);   //need to move this here for the DebugNonlinear function
  ml_sol.GetWriter()->SetDebugOutput(true);
  
  system.SetDebugNonlinear(true);
  system.SetDebugFunction(ComputeIntegral);
  //   system.SetMaxNumberOfNonLinearIterations(2);

    // ======= Solve ========================
  system.init();    // initialize and solve the system
  system.MGsolve();
  
//   ComputeIntegral(ml_prob);
 
    // ======= Final Print ========================
  std::vector < std::string > variablesToBePrinted;
  variablesToBePrinted.push_back("all");
  ml_sol.GetWriter()->Write(files.GetOutputPath()/*DEFAULT_OUTPUTDIR*/, "biquadratic", variablesToBePrinted);    // print solutions


  return 0;
}
Exemple #4
0
int main(int argc,char **args) {
  
  /// Init Petsc-MPI communicator
  FemusInit mpinit(argc,args,MPI_COMM_WORLD);

  Files files; 
        files.CheckIODirectories();
        files.RedirectCout();
	
  unsigned short nm,nr;
  std::cout<<"#MULTIGRID levels? (>=1) \n";
  //std::cin>>nm;
  nm=4;

  std::cout<<"#MAX_REFINEMENT levels? (>=0) \n";
  //std::cin>>nr;
  nr=0;
  int tmp=nm;
  nm+=nr;
  nr=tmp;

  const std::string infile = "./input/fsifirst.neu";
  
  double Lref = 1.;
  double Uref = 1.;
  double rhof = 1000.;
  double muf = 1.;
  double rhos = 1000;
  double ni = 0.4;
  double E = 5600000;
  
  MultiLevelMesh ml_msh(nm,nr,infile.c_str(),"fifth",Lref,SetRefinementFlag);
  
  MultiLevelSolution ml_sol(&ml_msh);
  
  //Start System Variables
  ml_sol.AddSolution("DX",LAGRANGE,SECOND,2);
  ml_sol.AddSolution("DY",LAGRANGE,SECOND,2);
//   ml_sol.AssociatePropertyToSolution("DX","Displacement"); // Add this line
//   ml_sol.AssociatePropertyToSolution("DY","Displacement"); // Add this line 
  ml_sol.AddSolution("U",LAGRANGE,SECOND,2);
  ml_sol.AddSolution("V",LAGRANGE,SECOND,2);
  
  //   ml_sol.PairSolution("U","DX"); // Add this line
  //   ml_sol.PairSolution("V","DY"); // Add this line 
  
  ml_sol.AddSolution("AX",LAGRANGE,SECOND,1,0);
  ml_sol.AddSolution("AY",LAGRANGE,SECOND,1,0);
  // Since the Pressure is a Lagrange multiplier it is used as an implicit variable
  ml_sol.AddSolution("P",DISCONTINOUS_POLYNOMIAL,FIRST,1);
  ml_sol.AssociatePropertyToSolution("P","Pressure"); // Add this line

  //Initialize (update Init(...) function)
  ml_sol.Initialize("All");

  //Set Boundary (update Dirichlet(...) function)
  ml_sol.AttachSetBoundaryConditionFunction(SetBoundaryCondition);
  ml_sol.GenerateBdc("DX","Steady");
  ml_sol.GenerateBdc("DY","Steady");
  ml_sol.GenerateBdc("U","Time_dependent");
  ml_sol.GenerateBdc("V","Steady");
  ml_sol.GenerateBdc("AX","Steady");
  ml_sol.GenerateBdc("AY","Steady");
  ml_sol.GenerateBdc("P","Steady");

  
  MultiLevelProblem ml_prob(&ml_sol);
  

  Parameter par(Lref,Uref);
  
  // Generate Solid Object
  Solid solid(par,E,ni,rhos,"Neo-Hookean");
  cout << "Solid properties: " << endl;
  cout << solid << endl;
  
  // Generate Fluid Object
  Fluid fluid(par,muf,rhof,"Newtonian");
  cout << "Fluid properties: " << endl;
  cout << fluid << endl;

  // Add fluid object
  ml_prob.parameters.set<Fluid>("Fluid") = fluid;
  
  // Add Solid Object
  ml_prob.parameters.set<Solid>("Solid") = solid;

  ml_msh.MarkStructureNode();
   
  //create systems
  // add the system FSI to the MultiLevel problem
  TransientMonolithicFSINonlinearImplicitSystem & system = ml_prob.add_system<TransientMonolithicFSINonlinearImplicitSystem> ("Fluid-Structure-Interaction");
  system.AddSolutionToSystemPDE("DX");
  system.AddSolutionToSystemPDE("DY");
  system.AddSolutionToSystemPDE("U");
  system.AddSolutionToSystemPDE("V");
  system.AddSolutionToSystemPDE("P");
  
  // init all the systems
  system.init();
   
  // System Fluid-Structure-Interaction
  system.SetAssembleFunction(AssembleMatrixResFSI);  
  system.SetMaxNumberOfLinearIterations(1);
  system.SetLinearConvergenceTolerance(1.e-8);  
  system.SetMgType(V_CYCLE);
  system.SetMaxNumberOfNonLinearIterations(4);
  system.SetNonLinearConvergenceTolerance(1.e-5);
  system.SetDirichletBCsHandling(PENALTY);
  
  //system.SetDirichletBCsHandling(ELIMINATION);
  
  // time loop parameter
  system.AttachGetTimeIntervalFunction(SetVariableTimeStep);
  const unsigned int n_timesteps = 5;
  const unsigned int write_interval = 1;
  
  std::vector<std::string> mov_vars;
  mov_vars.push_back("DX");
  mov_vars.push_back("DY");
  VTKWriter vtkio(&ml_sol);
  vtkio.SetMovingMesh(mov_vars);
  
  for (unsigned time_step = 0; time_step < n_timesteps; time_step++) {
   
    // Solving Fluid-Structure-Interaction system
    std::cout << std::endl;
    std::cout << " *********** Fluid-Structure-Interaction ************  " << std::endl;
    system.solve();
   
    //The update of the acceleration must be done before the update of the other variables
    system.NewmarkAccUpdate();
    
    //update Solution
    system.UpdateSolution();

    // print solution
    if ( !(time_step%write_interval) ) {
        
      //print solution 
      std::vector<std::string> print_vars;
      print_vars.push_back("DX");
      print_vars.push_back("DY");
      print_vars.push_back("U");
      print_vars.push_back("V");
      print_vars.push_back("P");
      
//       ml_prob.printsol_vtu_inline("biquadratic",print_vars,time_step);
      vtkio.write(files.GetOutputPath(),"biquadratic",print_vars,time_step);
    }
  
  } //end loop timestep
  

  // Destroy all the new systems
  ml_prob.clear();
   
  return 0;
}
Exemple #5
0
 int main(int argc, char** argv) {

#ifdef HAVE_LIBMESH
   libMesh::LibMeshInit init(argc,argv);
#else   
   FemusInit init(argc,argv);
#endif
   
 // ======= Files ========================
  Files files; 
        files.ConfigureRestart();
        files.CheckIODirectories();
        files.CopyInputFiles();
        files.RedirectCout();

  // ======= Physics Input Parser ========================
  FemusInputParser<double> physics_map("Physics",files.GetOutputPath());

  const double rhof   = physics_map.get("rho0");
  const double Uref   = physics_map.get("Uref");
  const double Lref   = physics_map.get("Lref");
  const double  muf   = physics_map.get("mu0");

  const double  _pref = rhof*Uref*Uref;           physics_map.set("pref",_pref);
  const double   _Re  = (rhof*Uref*Lref)/muf;     physics_map.set("Re",_Re);
  const double   _Fr  = (Uref*Uref)/(9.81*Lref);  physics_map.set("Fr",_Fr);
  const double   _Pr  = muf/rhof;                 physics_map.set("Pr",_Pr);

  // ======= Mesh =====
  const unsigned NoLevels = 3;
  const unsigned dim = 2;
  const GeomElType geomel_type = QUAD;
  GenCase mesh(NoLevels,dim,geomel_type,"inclQ2D2x2.gam");
          mesh.SetLref(1.);  
	  
  // ======= MyDomainShape  (optional, implemented as child of Domain) ====================
  FemusInputParser<double> box_map("Box",files.GetOutputPath());
  Box mybox(mesh.get_dim(),box_map);
      mybox.InitAndNondimensionalize(mesh.get_Lref());

          mesh.SetDomain(&mybox);    
	  
          mesh.GenerateCase(files.GetOutputPath());

          mesh.SetLref(Lref);
      mybox.InitAndNondimensionalize(mesh.get_Lref());
	  
          XDMFWriter::ReadMeshAndNondimensionalizeBiquadraticHDF5(files.GetOutputPath(),mesh); 
	  XDMFWriter::PrintMeshXDMF(files.GetOutputPath(),mesh,BIQUADR_FE);
          XDMFWriter::PrintMeshLinear(files.GetOutputPath(),mesh);
	  
  //gencase is dimensionalized, meshtwo is nondimensionalized
  //since the meshtwo is nondimensionalized, all the BC and IC are gonna be implemented on a nondimensionalized mesh
  //now, a mesh may or may not have an associated domain
  //moreover, a mesh may or may not be read from file
  //the generation is dimensional, the nondimensionalization occurs later
  //Both the Mesh and the optional domain must be nondimensionalized
  //first, we have to say if the mesh has a shape or not
  //that depends on the application, it must be put at the main level
  //then, after you know the shape, you may or may not generate the mesh with that shape 
  //the two things are totally independent, and related to the application, not to the library

  // ===== QuantityMap : this is like the MultilevelSolution =========================================
  QuantityMap  qty_map;
  qty_map.SetMeshTwo(&mesh);
  qty_map.SetInputParser(&physics_map);

  Pressure       pressure("Qty_Pressure",qty_map,1,LL);             qty_map.AddQuantity(&pressure);
  VelocityX     velocityX("Qty_Velocity0",qty_map,1,QQ);            qty_map.AddQuantity(&velocityX);
  VelocityY     velocityY("Qty_Velocity1",qty_map,1,QQ);            qty_map.AddQuantity(&velocityY);
  Temperature temperature("Qty_Temperature",qty_map,1,QQ);          qty_map.AddQuantity(&temperature);
  TempLift       templift("Qty_TempLift",qty_map,1,QQ);             qty_map.AddQuantity(&templift);  
  TempAdj         tempadj("Qty_TempAdj",qty_map,1,QQ);              qty_map.AddQuantity(&tempadj);  
  // ===== end QuantityMap =========================================
  
  // ====== Start new main =================================
  
  MultiLevelMesh ml_msh;
  ml_msh.GenerateCoarseBoxMesh(8,8,0,0,1,0,2,0,0,QUAD9,"fifth"); //   ml_msh.GenerateCoarseBoxMesh(numelemx,numelemy,numelemz,xa,xb,ya,yb,za,zb,elemtype,"fifth");
  ml_msh.RefineMesh(NoLevels,NoLevels,NULL);
  ml_msh.PrintInfo();
  
  ml_msh.SetWriter(XDMF);
  //ml_msh.GetWriter()->write(files.GetOutputPath(),"biquadratic");
  
  ml_msh.SetDomain(&mybox);    
	  
  MultiLevelSolution ml_sol(&ml_msh);
  ml_sol.AddSolution("Qty_Temperature",LAGRANGE,SECOND,0);
  ml_sol.AddSolution("Qty_TempLift",LAGRANGE,SECOND,0);
  ml_sol.AddSolution("Qty_TempAdj",LAGRANGE,SECOND,0);
  ml_sol.AddSolutionVector(ml_msh.GetDimension(),"Qty_Velocity",LAGRANGE,SECOND,0);
  ml_sol.AddSolution("Qty_Pressure",LAGRANGE,FIRST,0);
  ml_sol.AddSolution("Qty_TempDes",LAGRANGE,SECOND,0,false); //this is not going to be an Unknown! //moreover, this is not going to need any BC (i think they are excluded with "false") // I would like to have a Solution that is NOT EVEN related to the mesh at all... just like a function "on-the-fly"

  // ******* Set problem *******
  MultiLevelProblem ml_prob(&ml_sol);
  ml_prob.SetMeshTwo(&mesh);
  ml_prob.SetQruleAndElemType("fifth");
  ml_prob.SetInputParser(&physics_map);
  ml_prob.SetQtyMap(&qty_map); 
  
  // ******* Initial condition *******
  ml_sol.InitializeMLProb(&ml_prob,"Qty_Temperature",SetInitialCondition);  
  ml_sol.InitializeMLProb(&ml_prob,"Qty_TempLift",SetInitialCondition);  
  ml_sol.InitializeMLProb(&ml_prob,"Qty_TempAdj",SetInitialCondition);  
  ml_sol.InitializeMLProb(&ml_prob,"Qty_Velocity0",SetInitialCondition);  
  ml_sol.InitializeMLProb(&ml_prob,"Qty_Velocity1",SetInitialCondition);  
  ml_sol.InitializeMLProb(&ml_prob,"Qty_Pressure",SetInitialCondition); 
  ml_sol.InitializeMLProb(&ml_prob,"Qty_TempDes",SetInitialCondition); 

  /// @todo you have to call this before you can print 
  /// @todo I can also call it after instantiation MLProblem  
  /// @todo I cannot call it with "All" and with a FUNCTION, because I need the string for "All" as a variable
  /// @todo Have to say that you have to call this initialize BEFORE the generation of the boundary conditions;
  /// if you called this after, it would superimpose the BOUNDARY VALUES 
  /// @todo you have to initialize also those variables which are NOT unknowns!
  
  // ******* Set boundary function function *******
  ml_sol.AttachSetBoundaryConditionFunctionMLProb(SetBoundaryCondition);
  
  // ******* Generate boundary conditions *******
  ml_sol.GenerateBdc("Qty_Temperature","Steady",&ml_prob);
  ml_sol.GenerateBdc("Qty_TempLift","Steady",&ml_prob);
  ml_sol.GenerateBdc("Qty_TempAdj","Steady",&ml_prob);
  ml_sol.GenerateBdc("Qty_Velocity0","Steady",&ml_prob);
  ml_sol.GenerateBdc("Qty_Velocity1","Steady",&ml_prob);
  ml_sol.GenerateBdc("Qty_Pressure","Steady",&ml_prob);

  
  // ******* Debug *******
  ml_sol.SetWriter(VTK);
  std::vector<std::string> print_vars(1); print_vars[0] = "All"; // we should find a way to make this easier
  ml_sol.GetWriter()->write(files.GetOutputPath(),"biquadratic",print_vars);

  
//===============================================
//================== Add EQUATIONS AND ======================
//========= associate an EQUATION to QUANTITIES ========
//========================================================
// not all the Quantities need to be unknowns of an equation

  SystemTwo & eqnNS = ml_prob.add_system<SystemTwo>("Eqn_NS");
  
          eqnNS.AddSolutionToSystemPDEVector(ml_msh.GetDimension(),"Qty_Velocity");
          eqnNS.AddSolutionToSystemPDE("Qty_Pressure");
	  
          eqnNS.AddUnknownToSystemPDE(&velocityX); 
          eqnNS.AddUnknownToSystemPDE(&velocityY); 
          eqnNS.AddUnknownToSystemPDE(&pressure);
	  
	  eqnNS.SetAssembleFunction(GenMatRhsNS);
  

  SystemTwo & eqnT = ml_prob.add_system<SystemTwo>("Eqn_T");
  
         eqnT.AddSolutionToSystemPDE("Qty_Temperature");
         eqnT.AddSolutionToSystemPDE("Qty_TempLift");
         eqnT.AddSolutionToSystemPDE("Qty_TempAdj");
	 
         eqnT.AddUnknownToSystemPDE(&temperature);
         eqnT.AddUnknownToSystemPDE(&templift);
         eqnT.AddUnknownToSystemPDE(&tempadj); //the order in which you add defines the order in the matrix as well, so it is in tune with the assemble function
	 
	 eqnT.SetAssembleFunction(GenMatRhsT);
  
//================================ 
//========= End add EQUATIONS  and ========
//========= associate an EQUATION to QUANTITIES ========
//================================

//Ok now that the mesh file is there i want to COMPUTE the MG OPERATORS... but I want to compute them ONCE and FOR ALL,
//not for every equation... but the functions belong to the single equation... I need to make them EXTERNAL
// then I'll have A from the equation, PRL and REST from a MG object.
//So somehow i'll have to put these objects at a higher level... but so far let us see if we can COMPUTE and PRINT from HERE and not from the gencase
	 
 
//once you have the list of the equations, you loop over them to initialize everything

   for (MultiLevelProblem::const_system_iterator eqn = ml_prob.begin(); eqn != ml_prob.end(); eqn++) {
     
   SystemTwo* sys = static_cast<SystemTwo*>(eqn->second);
   
  // ******* set MG-Solver *******
  sys->SetMgType(F_CYCLE);
  sys->SetLinearConvergenceTolerance(1.e-10);
  sys->SetNonLinearConvergenceTolerance(1.e-10);//1.e-5
  sys->SetNumberPreSmoothingStep(1);
  sys->SetNumberPostSmoothingStep(1);
  sys->SetMaxNumberOfLinearIterations(8);     //2
  sys->SetMaxNumberOfNonLinearIterations(15); //10
  
  // ******* Set Preconditioner *******
  sys->SetMgSmoother(GMRES_SMOOTHER);//ASM_SMOOTHER,VANKA_SMOOTHER
   
  // ******* init *******
  sys->init();
  
  // ******* Set Smoother *******
  sys->SetSolverFineGrids(GMRES);
  sys->SetPreconditionerFineGrids(ILU_PRECOND); 
  sys->SetTolerances(1.e-12,1.e-20,1.e+50,20);   /// what the heck do these parameters mean?

    // ******* Add variables to be solved *******  /// do we always need this?
  sys->ClearVariablesToBeSolved();
  sys->AddVariableToBeSolved("All");
  
    
  // ******* For Gmres Preconditioner only *******
  sys->SetDirichletBCsHandling(ELIMINATION);
  
  // ******* For Gmres Preconditioner only *******
//   sys->solve();

//=====================
    sys -> init_two();     //the dof map is built here based on all the solutions associated with that system
    sys -> _LinSolver[0]->set_solver_type(GMRES);  //if I keep PREONLY it doesn't run

//=====================
    sys -> init_unknown_vars();
//=====================
    sys -> _dofmap.ComputeMeshToDof();
//=====================
    sys -> initVectors();
//=====================
    sys -> Initialize();
///=====================
    sys -> _bcond.GenerateBdc();
//=====================
    GenCase::ReadMGOps(files.GetOutputPath(),sys);
    
    } 
	 
  // ======== Loop ===================================
  FemusInputParser<double> loop_map("TimeLoop",files.GetOutputPath());
  OptLoop opt_loop(files, loop_map); 
   
  opt_loop.TransientSetup(ml_prob);  // reset the initial state (if restart) and print the Case

  opt_loop.optimization_loop(ml_prob);

// at this point, the run has been completed 
  files.PrintRunForRestart(DEFAULT_LAST_RUN);
  files.log_petsc();
  
// ============  clean ================================
  ml_prob.clear();
  mesh.clear();
  
  
  return 0;
}
Exemple #6
0
int main(int argc,char **args) {

  bool Vanka=0, Gmres=0, Asm=0;
  if(argc >= 2) {
    if( !strcmp("vanka",args[1])) 	Vanka=1;
    else if( !strcmp("gmres",args[1])) 	Gmres=1;
    else if( !strcmp("asm",args[1])) 	Asm=1;
    
    if(Vanka+Gmres+Asm==0) {
      cout << "wrong input arguments!" << endl;
      exit(0);
    }
  }
  else {
    cout << "No input argument set default smoother = Gmres" << endl;
    Gmres=1;
  }
  
  /// Init Petsc-MPI communicator
  FemusInit mpinit(argc,args,MPI_COMM_WORLD);
  
  Files files; 
        files.CheckIODirectories();
        files.RedirectCout();

  /// INIT MESH =================================  
  
  unsigned short nm,nr;
  nm=2;
  std::cout<<"MULTIGRID levels: "<< nm << endl;

  nr=0;
  std::cout<<"MAX_REFINEMENT levels: " << nr << endl<< endl;
  
  int tmp=nm;  nm+=nr;  nr=tmp;
  
  char *infile = new char [50];
 
  sprintf(infile,"./input/nsbenc.neu");
  
  //Adimensional quantity (Lref,Uref)
  double Lref = 1.;
  double Uref = 1.;
  
  //Steadystate NonLinearMultiLevelProblem  
  //MultiLevelMesh ml_msh(nm,nr,infile,"seventh",Lref,SetRefinementFlag); 
  MultiLevelMesh ml_msh;
  ml_msh.ReadCoarseMesh(infile,"seventh",Lref);
  ml_msh.RefineMesh(nm,nr,NULL);
  
  // ml_msh.EraseCoarseLevels(2);
  
  MultiLevelSolution ml_sol(&ml_msh);
  
  // generate solution vector
  ml_sol.AddSolution("T",LAGRANGE,SECOND);
  ml_sol.AddSolution("U",LAGRANGE,SECOND);
  ml_sol.AddSolution("V",LAGRANGE,SECOND);
  // the pressure variable should be the last for the Schur decomposition
  ml_sol.AddSolution("P",DISCONTINOUS_POLYNOMIAL,FIRST);
  ml_sol.AssociatePropertyToSolution("P","Pressure");
 
  //Initialize (update Init(...) function)
  ml_sol.Initialize("U",InitVariableU);
  ml_sol.Initialize("V");
  ml_sol.Initialize("P");
  ml_sol.Initialize("T");
  
  //Set Boundary (update Dirichlet(...) function)
  ml_sol.AttachSetBoundaryConditionFunction(SetBoundaryCondition);
  ml_sol.GenerateBdc("U");
  ml_sol.GenerateBdc("V");
  ml_sol.GenerateBdc("P");
  ml_sol.GenerateBdc("T");
  
  MultiLevelProblem ml_prob(&ml_sol);
  
  // add fluid material
  Parameter parameter(Lref,Uref);
  
  // Generate fluid Object (Adimensional quantities,viscosity,density,fluid-model)
  Fluid fluid(parameter,0.001,1,"Newtonian",0.001,1.);
  cout << "Fluid properties: " << endl;
  cout << fluid << endl;
  
  ml_prob.parameters.set<Fluid>("Fluid") = fluid;
   
  
  //BEGIN Navier-Stokes Multilevel Problem
  std::cout << std::endl;
  std::cout << " *********** Navier-Stokes ************  " << std::endl;
    
  NonLinearImplicitSystem & system1 = ml_prob.add_system<NonLinearImplicitSystem> ("Navier-Stokes");
  system1.AddSolutionToSystemPDE("U");
  system1.AddSolutionToSystemPDE("V");
  system1.AddSolutionToSystemPDE("P");
  
  // Set MG Options
  system1.SetAssembleFunction(AssembleMatrixResNS);  
  system1.SetMaxNumberOfNonLinearIterations(3);
  system1.SetMaxNumberOfLinearIterations(2);
  system1.SetLinearConvergenceTolerance(1.e-10);
  system1.SetNonLinearConvergenceTolerance(1.e-04);
  system1.SetMgType(F_CYCLE);
  system1.SetNumberPreSmoothingStep(1);
  system1.SetNumberPostSmoothingStep(1);
      
  //Set Smoother Options
  if(Gmres) 		system1.SetMgSmoother(GMRES_SMOOTHER);
  else if(Asm) 		system1.SetMgSmoother(ASM_SMOOTHER);
  else if(Vanka)	system1.SetMgSmoother(VANKA_SMOOTHER);
  
  system1.init();
  
  std::string  AMR  = "yes";
  unsigned int maxAMRlevels 	= 6;
  std::string  AMRnorm="l2";
  double       AMRthreshold 	=0.001;
 
  system1.SetAMRSetOptions(AMR,maxAMRlevels,AMRnorm,AMRthreshold);
  
  //common smoother options
  system1.SetSolverFineGrids(GMRES);
  system1.SetPreconditionerFineGrids(ILU_PRECOND); 
  system1.SetTolerances(1.e-12,1.e-20,1.e+50,4);
  //for Vanka and ASM smoothers
  system1.ClearVariablesToBeSolved();
  system1.AddVariableToBeSolved("All");
  //system1.AddVariableToBeSolved("U");
  //system1.AddVariableToBeSolved("V");
  //system1.AddVariableToBeSolved("P");
  system1.SetNumberOfSchurVariables(1);
  //system1.SetElementBlockNumber(4);   
  system1.SetElementBlockNumber("All",1);     
  //for Gmres smoother
  system1.SetDirichletBCsHandling(PENALTY); 
   
  // Solve Navier-Stokes system
  ml_prob.get_system("Navier-Stokes").solve();
  //END Navier-Stokes Multilevel Problem
  
  
//   //BEGIN Temperature MultiLevel Problem
//   std::cout << std::endl;
//   std::cout << " *********** Temperature ************* " << std::endl;
//     
//   LinearImplicitSystem & system2 = ml_prob.add_system<LinearImplicitSystem> ("Temperature");
//   system2.AddSolutionToSystemPDE("T");
//   
//   
//   // Set MG Options
//   system2.SetAssembleFunction(AssembleMatrixResT);
//   system2.SetMaxNumberOfLinearIterations(6);
//   system2.SetLinearConvergenceTolerance(1.e-9);  
//   system2.SetMgType(V_CYCLE);
//   system2.SetNumberPreSmoothingStep(1);
//   system2.SetNumberPostSmoothingStep(1);
//    
//   //Set Smoother Options
//   if(Gmres) 		system2.SetMgSmoother(GMRES_SMOOTHER);
//   else if(Asm) 		system2.SetMgSmoother(ASM_SMOOTHER);
//   else if(Vanka)	system2.SetMgSmoother(VANKA_SMOOTHER);
//   
//   system2.init(); 
//   //common smoother option
//   system2.SetSolverFineGrids(GMRES); 
//   system2.SetTolerances(1.e-12,1.e-20,1.e+50,4);
//   system2.SetPreconditionerFineGrids(ILU_PRECOND);
//   //for Vanka and ASM smoothers
//   system2.ClearVariablesToBeSolved();
//   system2.AddVariableToBeSolved("All");
//   system2.SetNumberOfSchurVariables(0);
//   system2.SetElementBlockNumber(4);                
//   //for Gmres smoother
//   system2.SetDirichletBCsHandling(PENALTY); 
//   
//   // Solve Temperature system
//   ml_prob.get_system("Temperature").solve();
//   //END Temperature Multilevel Problem
//   
//   double l2normvarU = ml_sol.GetSolutionLevel(3)->GetSolutionName("U")->l2_norm(); 
//   
//   double l2normvarUStored = 16.313927822836003;
//   
//   std::cout << "Solution U l2norm: " << l2normvarU << std::endl; 
//   
//   if( fabs((l2normvarU - l2normvarUStored )/l2normvarUStored) > 1.e-6) 
//   {
//     exit(1);
//   }
//   
//   double l2normvarV = ml_sol.GetSolutionLevel(3)->GetSolutionName("V")->l2_norm(); 
//   
//   double l2normvarVStored = 6.0644257018060355;
//   
//   std::cout << "Solution V l2norm: " << l2normvarV << std::endl; 
//   
//   if( fabs((l2normvarV - l2normvarVStored )/l2normvarVStored )> 1.e-6) 
//   {
//     exit(1);
//   }
//   
//   double l2normvarP = ml_sol.GetSolutionLevel(3)->GetSolutionName("P")->l2_norm(); 
//   
//   double l2normvarPStored = 1.8202105018866834;
//   
//   std::cout << "Solution P l2norm: " << l2normvarP << std::endl; 
//   
//   if( fabs((l2normvarP - l2normvarPStored )/l2normvarPStored) > 1.e-6) 
//   {
//     exit(1);
//   }
//   
//   double l2normvarT = ml_sol.GetSolutionLevel(3)->GetSolutionName("T")->l2_norm(); 
//   
//   double l2normvarTStored = 219.68194612060503;
//   
//   std::cout << "Solution T l2norm: " << l2normvarT <<std::endl; 
//   
//   if( fabs((l2normvarT - l2normvarTStored )/l2normvarTStored) > 1.e-6) 
//   {
//     exit(1);
//   }
  
  std::vector<std::string> print_vars;
  print_vars.push_back("U");
  print_vars.push_back("V");
  print_vars.push_back("P");
  print_vars.push_back("T");
  
  GMVWriter gmvio(&ml_sol);
  gmvio.write(files.GetOutputPath(),"biquadratic",print_vars);
  
  
  
  //Destroy all the new systems
  ml_prob.clear();
    
  delete [] infile;
  return 0;
}
Exemple #7
0
int main(int argc,char **args) {

  // ======= Initialize ========================
  // init Petsc-MPI communicator
  FemusInit mpinit(argc, args, MPI_COMM_WORLD);
  
  // ======= Files ========================
  Files files; 
        files.CheckIODirectories();
        files.RedirectCout();

  // ======= Quad Rule ===================
  std::string fe_quad_rule("seventh");

  // ======= Mesh ========================
  //Nondimensional quantity (Lref)
  double Lref = 1.;
  
// 2d
//   const unsigned int nsub_x = 16;
//   const unsigned int nsub_y = 16;
//   const unsigned int nsub_z = 0;
//   const std::vector<double> xyz_min = {0.,0.,0.};
//   const std::vector<double> xyz_max = {1.,1.,0.};
//   const ElemType geom_elem_type = QUAD9;

// 1d
  const unsigned int nsub_x = 16;
  const unsigned int nsub_y = 0;
  const unsigned int nsub_z = 0;
  const std::vector<double> xyz_min = {0.,0.,0.};
  const std::vector<double> xyz_max = {1.,0.,0.};
  const ElemType geom_elem_type = EDGE3;
  
//    std::string input_file = "Lshape_longer_y.med";
//    std::string input_file = "Lshape.med";
//    std::string input_file = "circle_tri6.med";
//    std::string input_file = "ellipse_tri6.med";
//    std::string input_file = "ellipse_with_hole_tri6.med";
   std::string input_file = "interval.med";
   std::ostringstream mystream; mystream << "./" << DEFAULT_INPUTDIR << "/" << input_file;
  const std::string infile = mystream.str();
  
  MultiLevelMesh ml_msh;
    ml_msh.GenerateCoarseBoxMesh(nsub_x,nsub_y,nsub_z,xyz_min[0],xyz_max[0],xyz_min[1],xyz_max[1],xyz_min[2],xyz_max[2],geom_elem_type,fe_quad_rule.c_str());
//   ml_msh.ReadCoarseMesh(infile.c_str(),fe_quad_rule.c_str(),Lref);

  unsigned numberOfUniformLevels = 1;
  unsigned numberOfSelectiveLevels = 0;
  ml_msh.RefineMesh(numberOfUniformLevels , numberOfUniformLevels + numberOfSelectiveLevels, NULL);
  ml_msh.PrintInfo();

  // ======= Solution ========================
  MultiLevelSolution ml_sol(&ml_msh);  // define the multilevel solution and attach the mlMsh object to it
  const unsigned int time_dep_flag = 2;
  
  // ======= Unknowns and Fields ========================
  std::string unknown = "u";
  ml_sol.AddSolution(unknown.c_str(), LAGRANGE, FIRST, time_dep_flag);
  ml_sol.AddSolution("time", DISCONTINUOUS_POLYNOMIAL, ZERO, time_dep_flag);

  // ======= Problem ========================
  MultiLevelProblem ml_prob(&ml_sol);  // define the multilevel problem attach the ml_sol object to it

  ml_prob.SetQuadratureRuleAllGeomElems(fe_quad_rule);
  ml_prob.SetFilesHandler(&files);
  
  // ======= Initial values ========================
  ml_sol.Initialize("All");    // initialize all variables to zero
  ml_sol.Initialize(unknown.c_str(),   SetInitialCondition, &ml_prob);

  // ======= Boundary Conditions ========================
  ml_sol.AttachSetBoundaryConditionFunction(SetBoundaryCondition);  // attach the boundary condition function and generate boundary data
  ml_sol.GenerateBdc(unknown.c_str()); //"Time_dependent");

  // ======= System ========================
  TransientNonlinearImplicitSystem & system = ml_prob.add_system<TransientNonlinearImplicitSystem> ("Timedep");
  system.AddSolutionToSystemPDE(unknown.c_str());

  system.init();  // does it have to stay here or later?

  system.SetAssembleFunction(AssembleMatrixRes_VC);

  system.SetOuterSolver(PREONLY);
  system.SetSolverFineGrids(PREONLY);
  system.SetPreconditionerFineGrids(MLU_PRECOND);
  
//   system.SetMaxNumberOfLinearIterations(1);
//   system.SetAbsoluteLinearConvergenceTolerance(1.e-8);
//   system.SetMgType(V_CYCLE);
  system.SetMaxNumberOfNonLinearIterations(30);
  system.SetNonLinearConvergenceTolerance(1.e-8);

  //**************
  ml_sol.SetWriter(VTK);   //need to move this here for the DebugNonlinear function
  ml_sol.GetWriter()->SetDebugOutput(true);
//   system.SetDebugNonlinear(true);
  //**************
  
  const unsigned fine_lev = ml_sol._mlMesh->GetNumberOfLevels() - 1;
  
  const double total_time = 1.;  
  
  std::vector< unsigned int > n_steps =  {2000/*6*//*2, *//*4, 8, 16*/};
 
//   std::vector< MultiLevelSolution >  last_sol(n_steps.size(),  & ml_msh);  
//   std::vector< Solution >  last_sol(n_steps.size(),  ml_msh.GetLevel(fine_lev) );  
  std::vector< NumericVector* >  last_sol(n_steps.size());
  
  
  for (unsigned i = 0; i < n_steps.size(); i++) {
      
  const double interval_time = total_time/n_steps[i];
  
  system.SetIntervalTime(interval_time);
  
  const unsigned int write_interval = 1.; //n_steps[i];

  const bool detect_quench = false; // Set to 0 for no adaptation and 1 for adaptation (which starts at a specified solution magnitude)
     
     
  for (unsigned time_step = 0; time_step < n_steps[i]; time_step++) {
      
  // ======= Check for quenching ==========
    if ( detect_quench == true ) {
      if ( (ml_sol.GetSolutionLevel( fine_lev ) )->GetSolutionName( unknown.c_str() ).linfty_norm() >= 0.99 ) { std::cout << "Detected quenching" << std::endl; exit(0); }
    }
      
  // ======= Print ========================
    if ( !(time_step % write_interval) ) {

        std::vector < std::string > variablesToBePrinted;
        variablesToBePrinted.push_back("all");
        std::string run_prefix = "n_steps_" + std::to_string(n_steps[i]);
        ml_sol.GetWriter()->Write(run_prefix, files.GetOutputPath(), "biquadratic", variablesToBePrinted, time_step);    // print solutions

    }
    
    // ======= Solve ========================
    std::cout << std::endl;
    std::cout << " *********** Timedep ************ " << std::endl;

    system.SetOuterSolver(PREONLY);
    system.MGsolve();
    
    
      ml_sol.Set("time", SetInitialCondition, &ml_prob);
      
//       system.compute_convergence_rate();
      
    // ======= Update Solution ===============
    system.CopySolutionToOldSolution();
    
     
     bool adapt_flag = 0; // Set to 0 for no adaptation and 1 for adaptation (which starts at a specified solution magnitude)
     
      if ( adapt_flag == 1 ) {
      
        double AdaptStarter = 0.85; // Value of ||u||_\infty at which to start adaptation
        if ( (ml_sol.GetSolutionLevel( fine_lev ) )->GetSolutionName( unknown.c_str() ).linfty_norm() >= AdaptStarter ) {
     
            double NonlinearityTracker = 0.1 * Singularity::derivative( (ml_sol.GetSolutionLevel( fine_lev ) )->GetSolutionName( unknown.c_str() ).linfty_norm() ) ;
            double NewTime = std::min( system.GetIntervalTime(), NonlinearityTracker );
            double minTimeStep = 0.001; // Minimum step-size controller
            double NewTimeFixed = std::max( NewTime , minTimeStep );
            system.SetIntervalTime(NewTimeFixed);
          }    
     
        }
       

     } //end loop timestep
     
     //here is where we store the ends of the simulations
//      last_sol[i] =  ml_sol;
//      last_sol[i] = *( ml_sol.GetSolutionLevel( fine_lev ) )/*->GetSolutionName( unknown.c_str() )*/;
     last_sol[i] =  &( ml_sol.GetSolutionLevel( fine_lev ) )->GetSolutionName( unknown.c_str() );
  
  }

//   last_sol[0]->add(-1., *(last_sol[1]));    const double numerator   = last_sol[0]->linfty_norm();
//   last_sol[2]->add(-1., *(last_sol[1]));   const double denominator = last_sol[2]->linfty_norm();

  return 0;
}