Esempio n. 1
0
// maps:put/3 [21]
term_t cbif_put3(proc_t *proc, term_t *regs)
{
	term_t Key   = regs[0];
	term_t Value = regs[1];
	term_t Map   = regs[2];

	if (!is_boxed_map(Map))
		badarg(Map);

	t_map_t *m0 = (t_map_t *)peel_boxed(Map);
	int index = map_key_index(Key, m0->keys);
	if (index >= 0)
	{
		// same as update/3
		int size = map_size(m0);
		int needed = WSIZE(t_map_t) +size;
		uint32_t *p = heap_alloc(&proc->hp, needed);
		t_map_t *m1 = (t_map_t *)p;
		box_map(p, size, m0->keys);
		heap_set_top(&proc->hp, p);

		memcpy(m1->values, m0->values, size *sizeof(term_t));
		m1->values[index] = Value;

		return tag_boxed(m1);
	}
	else
	{
		uint32_t *q = peel_tuple(m0->keys);
		int size = *q++;
		term_t *ks = q;
	
		term_t kvs[] = {Key,Value};

		int needed = 1 +size+1 +2 +size+1;
		uint32_t *p = heap_alloc(&proc->hp, needed);
		term_t keys = tag_tuple(p);
		*p++ = size+1;
		term_t *ks1 = p;
		p += size+1;
		term_t out = tag_boxed(p);
		term_t *vs1 = p +WSIZE(t_map_t);
		box_map(p, size+1, keys);
		heap_set_top(&proc->hp, p);

		int size1 = map_merge(ks, m0->values, size, kvs, 1, ks1, vs1);
		assert(size1 == size+1);
		
		return out;
	}
}
Esempio n. 2
0
// maps:update/3 [18]
term_t cbif_update3(proc_t *proc, term_t *regs)
{
	term_t Key   = regs[0];
	term_t Value = regs[1];
	term_t Map   = regs[2];

	if (!is_boxed_map(Map))
		badarg(Map);

	t_map_t *m0 = (t_map_t *)peel_boxed(Map);
	int index = map_key_index(Key, m0->keys);
	if (index < 0)
		badarg(Key);
	int size = map_size(m0);
	int needed = WSIZE(t_map_t) +size;
	uint32_t *p = heap_alloc(&proc->hp, needed);
	t_map_t *m1 = (t_map_t *)p;
	box_map(p, size, m0->keys);
	heap_set_top(&proc->hp, p);

	memcpy(m1->values, m0->values, size *sizeof(term_t));
	m1->values[index] = Value;

	return tag_boxed(m1);
}
Esempio n. 3
0
// maps:new/0 [22]
term_t cbif_new0(proc_t *proc, term_t *regs)
{
	uint32_t *p = heap_alloc(&proc->hp, 2);
	term_t map = tag_boxed(p);
	box_map(p, 0, ZERO_TUPLE);
	heap_set_top(&proc->hp, p);
	return map;
}
Esempio n. 4
0
// maps:remove/2 [20]
term_t cbif_remove2(proc_t *proc, term_t *regs)
{
	term_t Key = regs[0];
	term_t Map = regs[1];

	if (!is_boxed_map(Map))
		badarg(Map);

	t_map_t *m = (t_map_t *)peel_boxed(Map);
	int index = map_key_index(Key, m->keys);
	if (index < 0)
		return Map;

	uint32_t *p = peel_tuple(m->keys);
	int size = *p++;
	term_t *ks = p;

	int needed = 1 +size-1 +WSIZE(t_map_t) +size-1;
	uint32_t *htop = heap_alloc(&proc->hp, needed);
	term_t keys = tag_tuple(htop);
	*htop++ = size-1;
	memcpy(htop, ks, index *sizeof(term_t));
	htop += index;
	memcpy(htop, ks +index +1, (size -index -1) *sizeof(term_t));
	htop += (size -index -1);
	term_t out = tag_boxed(htop);
	t_map_t *m1 = (t_map_t *)htop;
	box_map(htop, size-1, keys);
	heap_set_top(&proc->hp, htop);

	memcpy(m1->values, m->values, index *sizeof(term_t));
	memcpy(m1->values +index +1,
		    m->values +index +1, (size -index -1) *sizeof(term_t));
 
	return out;	
}
Esempio n. 5
0
// maps:from_list/1 [26]
term_t cbif_from_list1(proc_t *proc, term_t *regs)
{
	term_t List = regs[0];
	if (!is_list(List))
		badarg(List);

	int len = list_len(List);
	term_t ks[len];		//XXX: imminent stack overflow
	term_t vs[len];
	int n = 0;

	term_t l = List;
	while (is_cons(l))
	{
		term_t *cons = peel_cons(l);
		if (!is_tuple(cons[0]))
			badarg(List);
		uint32_t *p = peel_tuple(cons[0]);
		if (*p++ != 2)
			badarg(List);
		term_t k = *p++;
		term_t v = *p++;

		if (n == 0 || is_term_smaller(k, ks[0]))
		{
			memmove(ks +1, ks, n *sizeof(term_t));
			memmove(vs +1, vs, n *sizeof(term_t));
			ks[0] = k;
			vs[0] = v;
			n++;
		}
		else
		{
			term_t *alpha = ks;
			term_t *beta = ks +n;
			// *alpha =< k
			while (beta > alpha+1)
			{
				term_t *mid = alpha + (beta -alpha +1)/2;
				if (is_term_smaller(k, *mid))
					beta = mid;
				else
					alpha = mid;
			}
			assert(beta == alpha+1);
			int index = alpha -ks;
			if (k == *alpha || are_terms_equal(k, *alpha, 1))
				vs[index] = v;
			else
			{
				index++;	// ks[index] > k now
				memmove(ks +index +1, ks +index, (n -index) *sizeof(term_t));
				memmove(vs +index +1, vs +index, (n -index) *sizeof(term_t));
				ks[index] = k;
				vs[index] = v;
				n++;
			}
		}
		l = cons[1];
	}

	if (!is_nil(l))
		badarg(List);

	int needed = 1 +n + WSIZE(t_map_t) +n;
	uint32_t *htop = heap_alloc(&proc->hp, needed);
	term_t keys = tag_tuple(htop);
	*htop++ = n;
	memcpy(htop, ks, n *sizeof(term_t));
	htop += n;
	term_t out = tag_boxed(htop);
	term_t *values = htop +WSIZE(t_map_t);
	box_map(htop, n, keys);
	heap_set_top(&proc->hp, htop);
	memcpy(values, vs, n *sizeof(term_t));

	return out;	
}
Esempio n. 6
0
// maps:merge/2 [23]
term_t cbif_merge2(proc_t *proc, term_t *regs)
{
	term_t Map1 = regs[0];
	term_t Map2 = regs[1];

	if (!is_boxed_map(Map1))
		badarg(Map1);
	if (!is_boxed_map(Map2))
		badarg(Map2);

	t_map_t *m1 = (t_map_t *)peel_boxed(Map1);
	uint32_t *p1 = peel_tuple(m1->keys);
	int size1 = *p1++;
	term_t *ks1 = p1;
	term_t *vs1 = m1->values;
	t_map_t *m2 = (t_map_t *)peel_boxed(Map2);
	uint32_t *p2 = peel_tuple(m2->keys);
	int size2 = *p2++;
	term_t *ks2 = p2;
	term_t *vs2 = m2->values;

	term_t mks[size1+size2];	//XXX: stack overflow
	term_t mvs[size1+size2];

	term_t *ks3 = mks;
	term_t *vs3 = mvs;

	int ss1 = size1;
	int ss2 = size2;

	int size = 0;
	while (size1 > 0 && size2 > 0)
	{
		term_t a = *ks1;
		term_t b = *ks2;
		if (is_term_smaller(a, b))
		{
			*ks3++ = *ks1++;
			*vs3++ = *vs1++;
			size1--;
		}
		else if (a == b || are_terms_equal(a, b, 1))
		{
			ks1++; vs1++;
			size1--;
			*ks3++ = *ks2++;
			*vs3++ = *vs2++;
			size2--;
		}
		else
		{
			*ks3++ = *ks2++;
			*vs3++ = *vs2++;
			size2--;
		}
		size++;
	}

	while (size1-- > 0)
	{
		*ks3++ = *ks1++;
		*vs3++ = *vs1++;
		size++;
	}

	while (size2-- > 0)
	{
		*ks3++ = *ks2++;
		*vs3++ = *vs2++;
		size++;
	}

	if (size == ss1 || size == ss2)
	{
		// reuse keys
		term_t keys = (size == ss1) ?m1->keys :m2->keys;
		int needed = WSIZE(t_map_t) +size;
		uint32_t *p = heap_alloc(&proc->hp, needed);
		term_t out = tag_boxed(p);
		term_t *values = p +WSIZE(t_map_t);
		box_map(p, size, keys);
		heap_set_top(&proc->hp, p);
		memcpy(values, mvs, size *sizeof(term_t));
		return out;
	}
	else
	{
		// new keys
		int needed = 1 +size +WSIZE(t_map_t) +size;
		uint32_t *p = heap_alloc(&proc->hp, needed);
		term_t keys = tag_tuple(p);
		*p++ = size;
		memcpy(p, mks, size *sizeof(term_t));
		term_t out = tag_boxed(p);
		term_t *values = p +WSIZE(t_map_t);
		box_map(p, size, keys);
		heap_set_top(&proc->hp, p);
		memcpy(values, mvs, size *sizeof(term_t));
		return out;
	}
}
Esempio n. 7
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;
}