コード例 #1
0
ファイル: main_result.cpp プロジェクト: MilosRadonjic/DMFT
int main()
{
  // initialize grid. params are read from input file
  GRID grid;

  // initialize a result object on grid
  Result result(&grid);

  // fill in Delta by initializing it to semi-circle
  InitDelta(DOStypes::SemiCircle, grid.get_N(), 0.2, 0.0, 0.01, 0.5, result.omega, result.Delta);

  result.mu = 0.1;
  result.n = 0.5;
  result.mu0 = 0.3; 
 
  //make a copy
  Result r2(result);
  //r2.CopyFrom(&result);
  r2.mu = 0.2;  
  r2.Delta[1000] = 7;

  result.PrintResult("Result.dat");
  r2.PrintResult("Result.dat.c");  

  Result r3(&grid);
  // this way mu, n and mu0 are not read
  r3.ReadFromFile("Result.dat.c");
  r3.n = 0.3;  
  r3.PrintResult("Result.dat.cc");  
  
  return 0;
}
コード例 #2
0
void find_boundary_component_germs(GRID const& G, FACETSET & C,
				   int& num_comps, int& num_facets)

{
  typedef GRID                          grid_type;
  typedef grid_types<GRID>              gt;
  typedef typename gt::Facet            Facet;
  typedef typename gt::FacetIterator    FacetIterator;
  typedef iscellinside_pred<grid_type>  inside;
  typedef BoundaryComponentEdgeIterator2D<grid_type, inside> BCFacetIterator;

  partial_grid_function<Facet,bool> marked(G,false);

  num_comps = num_facets = 0;
  for(FacetIterator f = G.FirstFacet(); ! f.IsDone(); ++f)
    if( (! marked(*f))  && (G.IsOnBoundary(*f))) {
      C.push_back(*f);
      num_comps++;
      BCFacetIterator bf(*f,inside(G));
      while(! bf.IsDone()) {
	num_facets++;
	marked[*bf] = true;
	++bf;
      }
    }
}
//#####################################################################
// Constructor
//#####################################################################
template<class T,class RW> OPENGL_COMPONENT_THIN_SHELLS_DEBUGGING_3D<T,RW>::
OPENGL_COMPONENT_THIN_SHELLS_DEBUGGING_3D(const GRID<TV> &grid,const std::string& directory)
    :OPENGL_COMPONENT("Thin Shells Debugging"),grid(grid),
    invalid_color_map(OPENGL_COLOR::Red()),
    opengl_density_valid_mask(grid,density_valid_mask,&invalid_color_map,OPENGL_SCALAR_FIELD_3D<T,bool>::DRAW_POINTS),
    directory(directory),frame_loaded(-1),valid(false),
    draw_density_valid_mask(false),draw_node_neighbors_visible(false),draw_face_corners_visible(false)
{
    is_animation=true;
    mac_grid=grid.Get_MAC_Grid();u_grid=grid.Get_X_Face_Grid();v_grid=grid.Get_Y_Face_Grid();w_grid=grid.Get_Z_Face_Grid();
}
コード例 #4
0
int count_boundary_facets(GRID const& G)
{
  typedef GRID                          grid_type;
  typedef grid_types<GRID>              gt;
  typedef typename gt::FacetIterator    FacetIterator;

  int nf = 0;
  for(FacetIterator f = G.FirstFacet(); ! f.IsDone(); ++f)
    if(G.IsOnBoundary(*f)) 
      ++nf;
  return nf;
}
コード例 #5
0
ファイル: quadsimpl.cpp プロジェクト: GuoXinxiao/meshlab
/*! Initializes the grid for smoothing and fitmaps
  *
  * \param m Reference mesh
  *
  */
void initGrid(CMesh & m)
{

  GRID* grid = new GRID();

  vcg::tri::UpdateBounding<CMesh>::Box(m);
  vcg::tri::UpdateEdges<CMesh>::Set(m);

  grid->Set(m.face.begin(), m.face.end());

//  grid->ShowStats(stdout);
  MyCollapse::grid() = grid;
  MyCollapseAdaptive::grid() = grid;

}
コード例 #6
0
void Compute_Cut_Geometries(const GRID<VECTOR<T,1> >& grid,const int num_ghost_cells,typename COLLISION_GEOMETRY_COLLECTION_POLICY<GRID<VECTOR<T,1> > >::GRID_BASED_COLLISION_GEOMETRY& collision_bodies_affecting_fluid,ARRAY<CUT_CELLS<T,1>*,VECTOR<int,1> >& cut_cells){
    typedef VECTOR<T,1> TV;
    typedef VECTOR<int,1> TV_INT;
    for(typename GRID<TV>::CELL_ITERATOR iterator(grid,num_ghost_cells);iterator.Valid();iterator.Next()){
        TV_INT index=iterator.Cell_Index();COLLISION_GEOMETRY_ID body_id;
        ARRAY<COLLISION_GEOMETRY_ID> collision_objects;collision_bodies_affecting_fluid.objects_in_cell.Get_Objects_For_Cell(index,collision_objects);
        if(!collision_objects.Size()) cut_cells(index)=0;
        else{
            cut_cells(index) = new CUT_CELLS<T,1>();cut_cells(index)->dominant_element=0;
            RANGE<TV> cell_volume=iterator.Bounding_Box();
            RAY<TV> l_to_r_ray(cell_volume.min_corner,cell_volume.max_corner-cell_volume.min_corner,true);l_to_r_ray.t_max=l_to_r_ray.direction.Normalize();l_to_r_ray.semi_infinite=false;
            RAY<TV> r_to_l_ray(cell_volume.max_corner,cell_volume.min_corner-cell_volume.max_corner,true);r_to_l_ray.t_max=r_to_l_ray.direction.Normalize();r_to_l_ray.semi_infinite=false;
            if(collision_bodies_affecting_fluid.Intersection_With_Any_Simplicial_Object(l_to_r_ray,body_id,&collision_objects)){
                int poly_index=cut_cells(index)->geometry.Append(POLYGON<TV>(RANGE<TV>(cell_volume.min_corner, l_to_r_ray.Point(l_to_r_ray.t_max))));
                TV centroid=ARRAYS_COMPUTATIONS::Average(cut_cells(index)->geometry(poly_index).X);

                cut_cells(index)->visibility.Resize(poly_index);
                if(!Is_Occluded_Cell_Center<T,1>(centroid,grid.Center(index),collision_bodies_affecting_fluid.objects_in_cell,collision_bodies_affecting_fluid.collision_geometry_collection,index)){
                    cut_cells(index)->dominant_element=poly_index;
                    cut_cells(index)->visibility(poly_index).Append(index);}
                if(!cut_cells(index)->dominant_element)
                    for(int node=1;!cut_cells(index)->dominant_element && node<=cut_cells(index)->geometry(poly_index).X.Size();++node)
                        if(!Is_Occluded_Cell_Center<T,1>(cut_cells(index)->geometry(poly_index).X(node),grid.Center(index),collision_bodies_affecting_fluid.objects_in_cell,collision_bodies_affecting_fluid.collision_geometry_collection,index)){
                            cut_cells(index)->dominant_element=poly_index;
                            cut_cells(index)->visibility(poly_index).Append(index);}

                TV_INT neighbor_cell_index=index-TV_INT::Axis_Vector(1);
                if(!Is_Occluded_Cell<T,1>(centroid,grid.Center(neighbor_cell_index),collision_bodies_affecting_fluid.objects_in_cell,collision_bodies_affecting_fluid.collision_geometry_collection,index,neighbor_cell_index))
                    cut_cells(index)->visibility(poly_index).Append(neighbor_cell_index);}
            if(collision_bodies_affecting_fluid.Intersection_With_Any_Simplicial_Object(r_to_l_ray,body_id,&collision_objects)){
                int poly_index=cut_cells(index)->geometry.Append(POLYGON<TV>(RANGE<TV>(r_to_l_ray.Point(r_to_l_ray.t_max),cell_volume.max_corner)));
                TV centroid=ARRAYS_COMPUTATIONS::Average(cut_cells(index)->geometry(poly_index).X);

                cut_cells(index)->visibility.Resize(poly_index);
                if(!Is_Occluded_Cell_Center<T,1>(centroid,grid.Center(index),collision_bodies_affecting_fluid.objects_in_cell,collision_bodies_affecting_fluid.collision_geometry_collection,index)){
                    cut_cells(index)->dominant_element=poly_index;
                    cut_cells(index)->visibility(poly_index).Append(index);}
                if(!cut_cells(index)->dominant_element)
                    for(int node=1;!cut_cells(index)->dominant_element && node<=cut_cells(index)->geometry(poly_index).X.Size();++node)
                        if(!Is_Occluded_Cell_Center<T,1>(cut_cells(index)->geometry(poly_index).X(node),grid.Center(index),collision_bodies_affecting_fluid.objects_in_cell,collision_bodies_affecting_fluid.collision_geometry_collection,index)){
                            cut_cells(index)->dominant_element=poly_index;
                            cut_cells(index)->visibility(poly_index).Append(index);}

                TV_INT neighbor_cell_index=index+TV_INT::Axis_Vector(1);
                if(!Is_Occluded_Cell<T,1>(centroid,grid.Center(neighbor_cell_index),collision_bodies_affecting_fluid.objects_in_cell,collision_bodies_affecting_fluid.collision_geometry_collection,index,neighbor_cell_index))
                    cut_cells(index)->visibility(poly_index).Append(neighbor_cell_index);}
            if(!cut_cells(index)->geometry.Size()){delete cut_cells(index);cut_cells(index)=0;}}}
}
コード例 #7
0
bool isSphereInside(SPHERES& spheres, int index, GRID &grid) {
  float x = spheres.coords[index * 4];
  float y = spheres.coords[index * 4 + 1];
  float z = spheres.coords[index * 4 + 2];
  float r = spheres.coords[index * 4 + 3];

  double xl = grid.rminloc[0] - r;
  double yl = grid.rminloc[1] - r;
  double zl = grid.rminloc[2] - r;

  double xr = grid.rmaxloc[0] + r;
  double yr = grid.rmaxloc[1] + r;
  double zr = grid.rmaxloc[2] + r;

  fromCoordsToSpheresCoords(yl, spheres.rmin[1], spheres.rmax[1]);
  fromCoordsToSpheresCoords(zl, spheres.rmin[2], spheres.rmax[2]);
  fromCoordsToSpheresCoords(yr, spheres.rmin[1], spheres.rmax[1]);
  fromCoordsToSpheresCoords(zr, spheres.rmin[2], spheres.rmax[2]);

  bool chkX, chkY, chkZ;
  chkX = chkY = chkZ = true;

  if (grid.getDimensionality() >= 2) {
    if ((grid.rmaxloc[1] - grid.rminloc[1]) >= (spheres.rmax[1] - spheres.rmin[1]))
      chkY = true;
    else {
      if (yl <= yr)
        chkY = ((y >= yl) && (y <= yr));
      else
        chkY = ((y >= yr) || (y <= yl));
    }
  }

  if (grid.getDimensionality() == 3) {
    if ((grid.rmaxloc[2] - grid.rminloc[2]) >= (spheres.rmax[2] - spheres.rmin[2]))
      chkZ = true;
    else {

      if (zl <= zr)
        chkZ = ((z >= zl) && (z <= zr));
      else
        chkZ = ((z >= zr) || (z <= zl));
    }
  }

  return chkX && chkY && chkZ;

}
コード例 #8
0
//#####################################################################
// Function Quadratic_Extrapolate
//#####################################################################
template<class TV,class T2> void EXTRAPOLATION_HIGHER_ORDER<TV,T2>::
Extrapolate_Face(const GRID<TV>& grid,const T_LEVELSET& phi,int ghost,ARRAY<T2,FACE_INDEX<TV::m> >& u,int iterations,int order,T distance)
{
    for(int i=1;i<=TV::m;i++){
        GRID<TV> node_grid(grid.Get_Axis_X_Face_Grid(i));
        Extrapolate_Node(node_grid,phi,ghost,u.Component(i),iterations,order,distance);}
}
コード例 #9
0
ファイル: test_levelset.cpp プロジェクト: hjwdzh/level-set
LEVELSET<GRID<TV> >* createTriMeshAndLevelSet(const char* name) {
	string n = string(name);
    TRIANGULATED_SURFACE<float>* triangles = new TRIANGULATED_SURFACE<float>();
    triangles->loadOBJ(name);
    triangles->Update_Bounding_Box_And_Gravity_Center();
    RANGE<TV> range = triangles->bounding_box;
    range.min -= TV(0.2, 0.2, 0.2);
    range.max += TV(0.2, 0.2, 0.2);
    GRID<TV>* grid = new GRID<TV>(TV_INT(40,40,40), range);
    ARRAY<3,float>* phi = new ARRAY<3, float>(grid->Domain_Indices());
    LEVELSET<GRID<TV> >* implicit_object = new LEVELSET<GRID<TV> >(*grid, *phi);
    SimLib::LEVELSET_MAKER<float> level_maker;
    ARRAY<3, int> closest_index;
    level_maker.Compute_Level_Set(*triangles, *grid, *phi, closest_index);
    ((LEVELSET<GRID<TV> >*)implicit_object)->Fast_Marching_Method(*triangles, closest_index);
    return implicit_object;
}
コード例 #10
0
//#####################################################################
// Function Calculate_Blackbody_Spectrum
//#####################################################################
// radiance_spectrum is in units of Watts/(steradian*m^2)/m 
// input grid of wavelengths in nanometers
template<class T> void BLACKBODY<T>::
Calculate_Radiance_Spectrum(const T temperature,const GRID<VECTOR<T,1> >& grid,ARRAY<T,VECTOR<int,1> >& radiance_spectrum) const
{
    T constant_1=T(plancks_constant*sqr(speed_of_light)/2),constant_2=T(plancks_constant*speed_of_light/boltzmanns_constant);
    for(int i=1;i<=grid.counts.x;i++){
        T lambda=grid.Axis_X(i,1);
        radiance_spectrum(i)=constant_1/(cube(lambda)*sqr(lambda)*(exp(constant_2/(lambda*temperature))-1));}
}
コード例 #11
0
//#####################################################################
// Function Negative_Material
//#####################################################################
template<class TV> typename TV::SCALAR IMPLICIT_OBJECT_INTERSECTOR<TV>::
Negative_Material_In_Cell(const GRID<TV>& grid,const TV_INT& cell_index,const bool force_full_refinement)
{
    // refinement step
    static TV_INT phi_indices[GRID<TV>::number_of_nodes_per_cell];grid.Nodes_In_Cell_From_Minimum_Corner_Node(cell_index,phi_indices);

    cell_particle_X.Resize(GRID<TV>::number_of_nodes_per_cell);
    for(int i=1;i<=GRID<TV>::number_of_nodes_per_cell;i++) cell_particle_X(i)=grid.Node(phi_indices[i-1]);
    cell_refinement_simplices.Remove_All();Refined_Object_Initialization_Helper(cell_refinement_simplices);

    int last_node=cell_particle_X.m;
    cell_phis.Resize(last_node);
    // compute phis for extant nodes
    T minimum_phi=FLT_MAX,maximum_phi=-FLT_MAX;

    for(int i=1;i<=last_node;i++){T& phi=cell_phis(i);
        phi=grid_nodal_phis(phi_indices[i-1]);
        if(phi<minimum_phi) minimum_phi=phi;
        if(phi>maximum_phi) maximum_phi=phi;}

    if(minimum_phi*maximum_phi>0 && min(abs(minimum_phi),abs(maximum_phi))>grid.Minimum_Edge_Length()) return minimum_phi<=0?full_cell_size:0;

    int unrefined_point_count=last_node;
    int last_parent_simplex=0,first_parent_simplex=1;
    for(int depth=0;depth<maximum_refinement_depth;depth++){
        first_parent_simplex=last_parent_simplex+1;
        last_parent_simplex=cell_refinement_simplices.m;
        for(int s=last_parent_simplex;s>=first_parent_simplex;s--){
            const T_ELEMENT simplex=cell_refinement_simplices(s);
            if(depth < minimum_refinement_depth || Refinement_Condition(cell_particle_X,cell_phis,simplex) || force_full_refinement){
                last_parent_simplex--;
                cell_refinement_simplices.Remove_Index_Lazy(s);
                Refine_Simplex(*this,cell_refinement_simplices,cell_particle_X,simplex);}}
        cell_phis.Resize(cell_particle_X.m);
        // compute phis for extant nodes
        for(int i=last_node+1;i<=cell_phis.m;i++) cell_phis(i)=Phi(cell_particle_X(i));
        last_node=cell_phis.m;}

    if(maximum_refinement_depth>0 && cell_phis.m==unrefined_point_count) return minimum_phi<=0?full_cell_size:0;
    // compute material
    T negative_material=0;
    for(int i=1;i<=cell_refinement_simplices.m;i++) negative_material+=T_SIMPLEX::Negative_Material(cell_particle_X,cell_phis,cell_refinement_simplices(i));
    return clamp(negative_material,(T)0,full_cell_size);
}
コード例 #12
0
void  manifold_checking_report(std::ostream& out, std::string const& grid_name, bool is_mf,
			       GRID const& G,
			       GF_F const& singular_facets, 
			       GF_V const& isolated_vertices,
			       GF_V const& singular_interior_vertices,
			       GF_V const& singular_boundary_vertices)
{
  using namespace GrAL;
  typedef grid_types<GF_V> vgt;
  typedef grid_types<GF_F> fgt;

  out << "Grid \"" << grid_name << "\" is" << (is_mf ? " " : " NOT " ) << "a manifold grid.\n";
  out << "|V|=" << G.NumOfVertices() << " |E|=" << G.NumOfEdges() << " |C|=" << G.NumOfCells() 
      << std::endl;

  if(! is_mf) {
    if(singular_facets.size() > 0) {
      out << singular_facets.size() << " singular edges: ";
      for(typename fgt::EdgeIterator e = GrAL::begin_x(singular_facets); !e.IsDone(); ++e)
	out << "[" << (*e).v1() << "," << (*e).v2() << "] ";
      out << "\n";
    }
    if(isolated_vertices.size() > 0) {
      out << isolated_vertices.size() << " isolated vertices: ";
      for(typename vgt::VertexIterator v = GrAL::begin_x(isolated_vertices); !v.IsDone(); ++v)
	out << v.handle() << ",";
      out << "\n";
    }
    if(singular_interior_vertices.size() > 0) {
      out << singular_interior_vertices.size() << " singular interior vertices: ";
      for(typename vgt::VertexIterator v = GrAL::begin_x(singular_interior_vertices); !v.IsDone(); ++v)
	out << v.handle() << ",";
      out << "\n";
    }
    if(singular_boundary_vertices.size() > 0) {
      out << singular_boundary_vertices.size() << " singular boundary vertices: ";
      for(typename vgt::VertexIterator v = GrAL::begin_x(singular_boundary_vertices); !v.IsDone(); ++v)
	out << v.handle() << ",";
      out << "\n";
    }
  }
}
コード例 #13
0
void write_complex2d(GRID const& G,   ::std::ostream& out, int offset, 
                     VCORR & G2Out_v, CCORR & G2Out_c)
{
  typedef grid_types<GRID>                  gt;
  typedef typename gt::Vertex               Vertex;
  typedef typename gt::Cell                 Cell;
  typedef typename gt::VertexIterator       VertexIterator;
  typedef typename gt::CellIterator         CellIterator;
  typedef typename gt::VertexOnCellIterator VertexOnCellIterator;

  out << G.NumOfVertices() << " " << G.NumOfCells() << "\n\n";

  // if GRID is a subrange type, we cannot initialized grid-functions
  // directly with G, but must get hold of the underlying grid.
  // This solution is not optimal. There could be a c-t branch
  // with an additional grid-type parameter for grid-functions.
  typedef element_traits<Vertex> et;
  typedef typename et::grid_type base_grid_type; // possibly != GRID
  Vertex dummy(*(G.FirstVertex()));
  base_grid_type const& baseG(dummy.TheGrid());

  grid_function<Vertex,int> VNum(baseG);
  int vnum = offset;
  for(VertexIterator v= G.FirstVertex(); ! v.IsDone(); ++v){
    //    out << Geo.coord(*v) << "\n"; 
    VNum[*v] = vnum;
    G2Out_v[v.handle()] = vnum;
    vnum++;
  }
  out << "\n";

  int cnum = offset;
  for(CellIterator c = GrAL::begin_x(G); !c.IsDone(); ++c){
    out	<< (*c).NumOfVertices() << "   ";
    G2Out_c[c.handle()] = cnum; ++cnum;
    for(VertexOnCellIterator vc = GrAL::begin_x(*c); ! vc.IsDone(); ++vc)
      out << VNum[*vc] << " ";
    out << "\n";
  }
}
コード例 #14
0
int getSolution(int n, int m)
{
     GRID g;
     VVV ava;
     VVB pos;
     MAP hash;
     g.resize(n);
     ava.resize(n);
     pos.resize(n);
     for (int i = 0; i < n; ++i)
     {
	  ava[i].resize(m);
	  g[i].resize(m);
	  pos[i].resize(m);
     }

     int dots = 0;
     int count = 0;
     for (int i = 0; i < n; ++i)
	  for (int j = 0; j < m; ++j)
	  {
	       char c;
	       cin >> g[i][j];
	       if (g[i][j] == '.')
		    dots++;
	       pos[i][j] = (g[i][j] == '.');
	  }
     for (int i = 0; i < n; ++i)
	  for (int j = 0; j < m; ++j)
	       preProcess(g, i, j,ava);
     for (int i = 1; i <= dots; ++i)
     {
	  int r = countQueen(g, i, 0, 0, ava, pos, hash);
	  if (r == 0)
	       break;
	  count += r;
	  count %= 1000000007;
     }
     return count;
}
コード例 #15
0
ファイル: main.cpp プロジェクト: Samuel-Lewis/Experiments
int main()
{
	// Generate new map
	CA* reg = new CA(40,40);
	GRID map = reg->getMap();


	// Print out the map
	char out = ' ';
	for (int x = 0; x < (int)map.size(); x++)
	{
		for (int y = 0; y < (int)map[x].size(); y++)
		{
			// map is full of bools, diff between them
			out = map[x][y] ? 'X' : ' ';
			std::cout << out;
		}

		std::cout << std::endl;
	}

	return 0;
}
コード例 #16
0
void write_complex2d(GRID const& G, GEOM const& Geo,  ::std::ostream& out, int offset)
{
  typedef grid_types<GRID>                  gt;
  typedef typename gt::Vertex               Vertex;
  typedef typename gt::Cell                 Cell;
  typedef typename gt::VertexIterator       VertexIterator;
  typedef typename gt::CellIterator         CellIterator;
  typedef typename gt::VertexOnCellIterator VertexOnCellIterator;

  out << G.NumOfVertices() << " " << G.NumOfCells() << "\n\n";

  // if GRID is a subrange type, we cannot initialized grid-functions
  // directly with G, but must get hold of the underlying grid.
  // This solution is not optimal. There could be a c-t branch
  // with an additional grid-type parameter for grid-functions.
  typedef element_traits<Vertex> et;
  typedef typename et::grid_type base_grid_type; // possibly != GRID
  Vertex dummy(*(G.FirstVertex()));
  ref_ptr<base_grid_type const> baseG(dummy.TheGrid());

  grid_function<Vertex,int> VNum(* baseG);
  int vnum = offset;
  for(VertexIterator v= G.FirstVertex(); ! v.IsDone(); ++v){
    out << std::setprecision(std::numeric_limits<double>::digits10) << Geo.coord(*v) << "\n"; 
    VNum[*v] = vnum;
    vnum++;
  }
  out << "\n";


  for(CellIterator c = G.FirstCell(); !c.IsDone(); ++c){
    out	<< GrAL::size<Vertex>(*c) << "  ";
    for(VertexOnCellIterator vc = GrAL::begin<Vertex>(*c); ! vc.IsDone(); ++vc)
      out << VNum[*vc] << " ";
    out << "\n";
  }
}
コード例 #17
0
//#####################################################################
// Function Quadratic_Extrapolate
//#####################################################################
template<class TV,class T2> void EXTRAPOLATION_HIGHER_ORDER<TV,T2>::
Extrapolate_Node(const GRID<TV>& grid,const T_LEVELSET& phi,int ghost,ARRAYS_ND_BASE<VECTOR<T2,TV::m> >& u,int iterations,int order,T distance)
{
    PHYSBAM_ASSERT(order>=1 && order<=3);
    PHYSBAM_ASSERT(!grid.Is_MAC_Grid());
    T dt=grid.dX.Max()/(TV::m+1);
    MAPPING m;
    ARRAY<TV> normal;
    ARRAY<VECTOR<STENCIL,TV::m> > stencil;
    Fill_Level(grid,phi,ghost,m,normal,stencil,order,distance);
    ARRAY<T2> du[3];
    du[0].Resize(m.max_solve_index(2*order+1));
    ARRAY<T2> tmp(m.max_solve_index(2*order+1));
    for(int i=m.max_solve_index(1)+1;i<=m.max_solve_index(2*order+1);i++) du[0](i)=u(m.index_to_node(i));
    for(int o=1;o<order;o++) Fill_un(m,grid.one_over_dX,normal,du[o-1],du[o],o,order);
    for(int i=0;i<order;i++) du[i](1)=FLT_MAX/100; // Sentinal values for ENO.
    tmp(1)=FLT_MAX/100;
    for(int o=order;o>0;o--) for(int i=1;i<=iterations;i++) Extrapolate_RK2(m,stencil,du[o-1],(o!=order?&du[o]:0),tmp,o,dt);
    for(int i=2;i<=m.max_solve_index(1);i++) u(m.index_to_node(i))=du[0](i);
}
コード例 #18
0
//#####################################################################
// Function Compute_Level_Set
//#####################################################################
template<class T> void LEVELSET_MAKER_UNIFORM_2D<T>::
Compute_Level_Set(SEGMENTED_CURVE_2D<T>& curve,GRID<TV>& grid,int ghost_cells,ARRAY<T,TV_INT>& phi)
{
    phi.Fill(FLT_MAX);
    T dx=grid.dX.Max();

    ARRAY<bool,TV_INT> done(grid.Domain_Indices(ghost_cells+1));
    for(int i=1;i<=curve.mesh.elements.m;i++){
        SEGMENT_2D<T> segment(curve.particles.X(curve.mesh.elements(i).x),curve.particles.X(curve.mesh.elements(i).y));
        RANGE<TV_INT> box(grid.Cell(segment.x1,3));
        box.Enlarge_To_Include_Point(grid.Cell(segment.x2,3));
        box=box.Intersect(box,grid.Domain_Indices(ghost_cells-1));
        if(box.Empty()) continue;
        for(UNIFORM_ARRAY_ITERATOR<TV::m> it(box.Thickened(1));it.Valid();it.Next()){
            TV X=grid.X(it.index);
            T dist=segment.Distance_From_Point_To_Segment(X);
            if(dist<abs(phi(it.index))+dx*1e-4 && dist<dx){
                bool new_sign=TV::Dot_Product(X-segment.x1,segment.Normal())<0;
                if(abs(dist-abs(phi(it.index)))<dx*1e-4 && new_sign != (phi(it.index)<0))
                    new_sign=curve.Inside(grid.X(it.index));
                if(abs(dist)<abs(phi(it.index))) phi(it.index)=dist;
                phi(it.index)=abs(phi(it.index))*(new_sign?-1:1);
                done(it.index)=true;}}}

    ARRAY<TV_INT> todo,next_todo;
    for(UNIFORM_GRID_ITERATOR_CELL<TV> it(grid);it.Valid();it.Next())
        if(phi(it.index)!=FLT_MAX)
            todo.Append(it.index);
    for(int layer=1;todo.m;layer++){
        while(todo.m){
            TV_INT index=todo.Pop();
            T next=sign(phi(index))*layer*dx;
            Compute_Level_Set_Helper(index+TV_INT(1,0),next,next_todo,phi);
            Compute_Level_Set_Helper(index-TV_INT(1,0),next,next_todo,phi);
            Compute_Level_Set_Helper(index+TV_INT(0,1),next,next_todo,phi);
            Compute_Level_Set_Helper(index-TV_INT(0,1),next,next_todo,phi);}
        todo.Exchange(next_todo);}
/*
    for(UNIFORM_GRID_ITERATOR_CELL<TV> it(grid);it.Valid();it.Next()){
        VECTOR<T,3> color=phi(it.index)>0?VECTOR<T,3>(0,1,0):VECTOR<T,3>(1,0,0);
        if(done(it.index)) color/=(T)3;
        Add_Debug_Particle(grid.X(it.index),color);}*/
    PHYSBAM_DEBUG_WRITE_SUBSTEP("Compute Level Set",0,1);

    LEVELSET_2D<GRID<TV> > levelset(grid,phi);
    FAST_MARCHING_METHOD_UNIFORM<GRID<TV> > fmm(levelset,ghost_cells);
    fmm.Fast_Marching_Method(phi,done);
}
コード例 #19
0
//#####################################################################
// Function Calculate
//#####################################################################
template<class T> void Calculate(SEGMENTED_CURVE_2D<T>& curve,const GRID<VECTOR<T,2> >& grid,ARRAY<T,VECTOR<int,2> >& phi,bool print_progress)
{
    bool bounding_box_defined=curve.bounding_box!=0;if(!bounding_box_defined) curve.Update_Bounding_Box();

    phi.Resize(1,grid.counts.x,1,grid.counts.y);

    T epsilon=(T)1e-8*grid.min_dX;
    int total_cells=grid.counts.x*grid.counts.y,cells_done=0,progress=-1;
    for(int i=1;i<=grid.counts.x;i++) for(int j=1;j<=grid.counts.y;j++){
        phi(i,j)=curve.Calculate_Signed_Distance(grid.X(i,j),epsilon);
        if(print_progress){
            cells_done++;int new_progress=(int)((T)100*cells_done/total_cells);
            if(new_progress > progress){
#ifndef COMPILE_WITHOUT_READ_WRITE_SUPPORT
                LOG::cout<<new_progress<<"% "<<std::flush;
#endif
                progress=new_progress;}}}
#ifndef COMPILE_WITHOUT_READ_WRITE_SUPPORT
    if(print_progress) LOG::cout<<std::endl;
#endif

    if(!bounding_box_defined){delete curve.bounding_box;curve.bounding_box=0;}
}
コード例 #20
0
ファイル: EqsKL2D.cpp プロジェクト: markuszi/Rismo2D
void EQS_KL2D::Execute( PROJECT* project, int steadyFlow )
{
  MODEL* model    = project->M2D;
  GRID*  rg       = project->M2D->region;

  NODE** node     = model->node;
  ELEM** elem     = model->elem;

  int np          = model->np;
  int ne          = model->ne;

  int diverged_cg = 0;

  double  theNorm = -1.0;

  double cm = project->KD.cm * project->KD.cd;

  model->Incinit();

  // print information on actual iteration -----------------------------------------------
  project->PrintTheCycle( 1 );
  REPORT::rpt.PrintTime( 1 );

  // set parameters according to time integration and relaxation -------------------------
  double th = project->timeint.thetaTurb;
  double dt = project->timeint.incTime.Getsec();

  if( fabs(th) < 1.0e-10  ||  fabs(dt) < 1.0e-10 )
  {
    REPORT::rpt.Error( kParameterFault, "theta or timeInterval too small (EQS_KL2D::execute - 1)" );
  }

  double thdt = 1.0 / dt / th;

  double dt_K;
  double relaxDt_KD = project->timeint.relaxTimeTurb.Getsec();

  int relaxMethod = project->relaxMethod;

  if( steadyFlow )
  {
    if( relaxMethod >= 3 ) // stationary flow time relaxed computation
    {
      dt_K = relaxDt_KD;
      relaxThdt_KD = 1.0 / dt_K;
    }
    else
    {
      dt_K = dt;
      relaxThdt_KD = 0.0;
    }

    for( int i=0; i<np; i++ )  node[i]->v.dKdt = 0.0;
  }

  else // instationary flow
  {
    if( relaxMethod >= 3 ) // instationary flow time relaxed computation
    {
      dt_K = relaxDt_KD;
    }
    else
    {
      dt_K = dt;
    }

    relaxThdt_KD = 1.0 / dt_K / th;

    // time prediction -------------------------------------------------------------------

    for( int i=0; i<np; i++ )
    {
      VARS* v = &(node[i]->v);
/*
      VARS* vo = &(node[i]->vo);

      v->K = vo->K  +  vo->dKdt * dt;

      v->dKdt = (1.0 - 1.0/th)*vo->dKdt + thdt*(v->K - vo->K);
*/
      v->dKdt = 0.0;
    }
  }


  if( model->Getinit() != modelInit )
  {
    initStructure = true;
    modelInit = model->Getinit();
  }


  // determine friction coefficients -----------------------------------------------------

  model->DoFriction( project );


  // set KD boundary conditions ----------------------------------------------------------

  model->SetBoundKD( project );


  // set up equation numbers -------------------------------------------------------------

  project->fix[0] = BCON::kFixK;

  project->elemKind = ELEM::kRegion;

  SetEqno( model, 1, 0, 0, project->fix, project->elemKind );

  double* B = (double*) MEMORY::memo.Array_eq( neq );
  double* X = (double*) MEMORY::memo.Array_eq( neq );

  if( !B || !X )
    REPORT::rpt.Error( kMemoryFault, "can not allocate memory (EQS_KL2D::execute - 2)" );


  // -------------------------------------------------------------------------------------

  for( int it=0; it<project->actualCycit; it++ )
  {
    double relax;

    int conv = true;


    // print information on actual iteration ---------------------------------------------

    if( it )
    {
      project->PrintTheCycle( it+1 );
      REPORT::rpt.PrintTime( 2 );
    }


    // compute dissipation ---------------------------------------------------------------

    Dissipation( project );


    // initialize Reynolds stresses and eddy viscosity -----------------------------------

    rg->Turbulence( project );


    // solve equations with frontal solving algorithm ------------------------------------

    for( int i=0; i<neq; i++ ) X[i] = 0.0;

    diverged_cg = Solve( model, neq, B, X, project );


    // statistics ------------------------------------------------------------------------

    int    noAbs, noPer;
    double maxAbs, maxPer, avAbs, avPer;

    REPORT::rpt.Message( 1, "\n\n %s\n\n %s\n\n",
                            "(KLCycle)       convergence parameters ...",
                            " variable   node          average        maximum" );


    Update( model, &project->subdom,
            X, 0, kVarK, &maxAbs, &maxPer, &avAbs, &avPer, &noAbs, &noPer );

    REPORT::rpt.Message( 1, "      %1c     %5d       %12.5le   %12.5le %s\n",
                            'K', noAbs, avAbs, maxAbs, "     (abs)" );

    REPORT::rpt.Message( 1, "      %1c     %5d       %12.5lf   %12.5lf %s\n\n",
                            ' ', noPer, avPer, maxPer, "     ( % )" );

    if( fabs(maxAbs) > project->convKD )  conv = false;


    // determine relaxation parameter for NEWTON-RAPHSON ---------------------------------

    double minK = 0.0;
    double maxK = 0.0;

    switch( relaxMethod )
    {
      case 2:
        theNorm = 0.0;
        maxK    = 0.0;

        for( int i=0; i<np; i++ )
        {
          int    eqno;
          double dK = 0.0;

          eqno = GetEqno( node[i], 0 );
          if( eqno >= 0 )  dK = fabs( X[eqno] );

          theNorm += dK*dK;

          if( dK > maxK )  maxK = dK;
        }

        theNorm = sqrt( theNorm );

        relax = project->maxDeltaKD / maxK;

        if( relax > 1.0 )  relax = 1.0;

        REPORT::rpt.Message( 1, "\n %s %12.4le\n %s %12.4le\n\n",
                                "                relaxation:   norm  =", theNorm,
                                "                              relax =", relax );
        break;

      case 3:
      case 4:
        REPORT::rpt.Message( 1, "\n %s %12.4le\n",
                                "(KLCycle)       relaxed time: dt_K =", dt_K );

        if( dt_K < dt )  conv = false;

        theNorm = 0.0;
        maxK    = 0.0;

        for( int i=0; i<np; i++ )
        {
          int    eqno;
          double dK = 0.0;

          eqno = GetEqno( node[i], 0 );
          if( eqno >= 0 )  dK = fabs( X[eqno] );

          theNorm += dK*dK;

          if( dK > maxK )  maxK = dK;
        }

        theNorm = sqrt( theNorm );

        relax = project->maxDeltaKD / maxK;

        dt_K *= relax;

        if( dt_K > dt )          dt_K = dt;
        if( dt_K < relaxDt_KD )  dt_K = relaxDt_KD;

        if( steadyFlow ) relaxThdt_KD = 1.0 / dt_K;
        else             relaxThdt_KD = 1.0 / dt_K / th;

        if( relax > 1.0 )  relax = 1.0;

        REPORT::rpt.Message( 1, "\n %s %12.4le\n %s %12.4le\n\n",
                                "                relaxation:   norm  =", theNorm,
                                "                              relax =", relax );
        break;

      default:
        relax = 1.0;

        theNorm = 0.0;

        for( int i=0; i<np; i++ )
        {
          int    eqno;
          double dK = 0.0;

          eqno = GetEqno( node[i], 0 );
          if( eqno >= 0 )  dK = fabs( X[eqno] );

          theNorm += dK*dK;
        }

        theNorm = sqrt( theNorm );

        REPORT::rpt.Message( 1, "\n %s %12.4le\n %s %12.4le\n\n",
                                "                relaxation:   norm  =", theNorm,
                                "                              relax =", relax );
        break;
    }


    // update ----------------------------------------------------------------------------

    for( int i=0; i<np; i++ )
    {
      int n = GetEqno( node[i], 0 );
      if( n >= 0 )  node[i]->v.K += relax * X[n];
    }


    // check for range of values ---------------------------------------------------------

    int first = true;
    int jk = 0;

    for( int i=0; i<np; i++ )
    {
      if( first )
      {
        first = false;
        minK =
        maxK = node[i]->v.K;
      }
      else
      {
        if( node[i]->v.K < minK )  minK = node[i]->v.K;
        if( node[i]->v.K > maxK )  maxK = node[i]->v.K;
      }

      if( node[i]->v.K <= 0.0 )
      {
//        node[i]->v.K = project->minK;
        node[i]->v.K = sqrt( node[i]->vt * node[i]->v.D / cm );

        if( GetEqno(node[i],0) >= 0 )  jk++;
      }
    }


    if( jk )
    {
      REPORT::rpt.Message( 1, " (KLCycle)       %d %s\n\n", jk, "nodes with K out of range");
    }


    REPORT::rpt.Message( 1, " (KLCycle)       minimum of K: %le\n", minK );
    REPORT::rpt.Message( 1, "                 maximum of K: %le\n", maxK );


    // compute midside values (linear interpolation) -------------------------------------

    for( int e=0; e<ne; e++ )
    {
      ELEM* el = elem[e];

      int ncn = el->Getncn();
      int nnd = el->Getnnd();

      for( int i=ncn; i<nnd; i++ )
      {
        // get left and right corner node to midside node i

        int    il, ir;
        double left, rght;

        el->GetQShape()->getCornerNodes( i, &il, &ir );

        left = el->nd[il]->v.K;
        rght = el->nd[ir]->v.K;
        el->nd[i]->v.K = 0.5 * (left + rght);
      }
    }


    // compute time derivatives ----------------------------------------------------------

    rg->ReportCuPe( dt, project->vk );


    if( !steadyFlow )
    {
      double iTheta;

      iTheta  = 1.0  -  1.0 / project->timeint.thetaTurb;

      for( int i=0; i<np; i++ )
      {
        if(     isFS(node[i]->flag, NODE::kDry)
            ||  isFS(node[i]->flag, NODE::kMarsh) )
        {
          node[i]->v.dKdt = 0.0;
        }

        else
        {
          double K, pK, pdKdt;
          VARS *v, *vo;

          v  = &(node[i]->v);
          vo = &(node[i]->vo);

          K     = v->K;
          pK    = vo->K;
          pdKdt = vo->dKdt;


          // compute derivatives at actual time step

          node[i]->v.dKdt = iTheta*pdKdt + thdt*(K - pK);
        }
      }
    }


    if( conv )  break;
  }


  MEMORY::memo.Detach( B );
  MEMORY::memo.Detach( X );


  if( diverged_cg )  project->errLevel |= diverged_cg | kErr_no_conv_cg;
}
コード例 #21
0
ファイル: EqsKL2D.cpp プロジェクト: markuszi/Rismo2D
void EQS_KL2D::Dissipation( PROJECT* project )
{
  double cm = project->KD.cm;
  double cd = project->KD.cd;

  MODEL* model = project->M2D;
  GRID*  rg    = model->region;


  // initialization ----------------------------------------------------------------------

  for( int n=0; n<rg->Getnp(); n++ )
  {
    NODE* nd = rg->Getnode(n);
    nd->v.D = 0.0;
  }

  double* ndarea = (double*) MEMORY::memo.Array_nd( rg->Getnp() );

  for( int n=0; n<rg->Getnp(); n++ )  ndarea[n] = 0.0;


  // -------------------------------------------------------------------------------------
  // loop on elements
  // -------------------------------------------------------------------------------------

  for( int e=0; e<rg->Getne(); e++ )
  {
    ELEM* el = rg->Getelem(e);

    if( !isFS(el->flag, ELEM::kDry) )
    {
      TYPE* type = TYPE::Getid( el->type );

      int nnd = el->Getnnd();

      NODE** nd = el->nd;


      // ---------------------------------------------------------------------------------
      // compute coordinates relative to first node
      // ---------------------------------------------------------------------------------

      double xmin, xmax, ymin, ymax;
      double x[kMaxNodes2D], y[kMaxNodes2D];

      xmin = xmax = x[0] = nd[0]->x;
      ymin = ymax = y[0] = nd[0]->y;

      for( int i=1; i<nnd; i++ )
      {
        if( nd[i]->x < xmin )  xmin = nd[i]->x;
        if( nd[i]->x > xmax )  xmax = nd[i]->x;

        if( nd[i]->y < ymin )  ymin = nd[i]->y;
        if( nd[i]->y > ymax )  ymax = nd[i]->y;

        x[i] = nd[i]->x - x[0];
        y[i] = nd[i]->y - y[0];
      }

      x[0] = y[0] = 0.0;


      double lm = type->lm;


      // grid depending lm ---------------------------------------------------------------

      if( isFS(project->actualTurb, BCONSET::kVtLES) )
      {
        lm *= sqrt( (xmax-xmin)*(ymax-ymin) );
      }


      double area = el->area();

      for( int i=0; i<nnd; i++ )
      {
        double K  = nd[i]->v.K;
        if( K <= 0.0 )  K = project->minK;

        double ls = lm / sqrt( sqrt(cm*cm*cm/cd) );

        nd[i]->v.D += area * cd * sqrt(K*K*K) / ls;

        ndarea[nd[i]->Getno()] += area;
      }
    }
  }


  for( int n=0; n<rg->Getnp(); n++ )
  {
    NODE* nd = rg->Getnode(n);

    if( ndarea[n] > 0.0 )  nd->v.D /= ndarea[n];
  }

  MEMORY::memo.Detach( ndarea );
}
コード例 #22
0
ファイル: Preco_ilut.cpp プロジェクト: markuszi/Rismo2D
void PRECO_ILUT::Solve( PROJECT* project, EQS* eqs, double* B, double* X )
{
  int      neq    = crsi->m_neq;
  int      neq_dn = crsi->m_neq_dn;
  int      neq_up = crsi->m_neq_up;

  int*     width  = crsi->m_width;
  int**    index  = crsi->m_index;
  REALPR** ILU    = crsi->m_A;


  ////////////////////////////////////////////////////////////////////////////////////////
  // 1.  forward solve: manipulate vector B with lower part of matrix ILU
  //
  // 1.1 MPI: forward solve for interior subdomain nodes

# ifdef _MPI_DBG
  REPORT::rpt.Output( " (PRECO_ILUT::Solve)     starting with 1.1\n" );
# endif

  for( int i=0; i<neq_up; i++ )
  {
    X[i] = B[i];

    for( int j=1; j<width[i]; j++ )
    {
      int eq = index[i][j];

      if( eq < i )  // L-matrix
      {
        X[i] += ILU[i][j] * X[eq];
      }
    }
  }


  ////////////////////////////////////////////////////////////////////////////////////////
  // 1.2 MPI communication:
  //     receive from subdomains with smaller pid  (2 <- 1)
  //     s < pid  ==> upstream interface nodes

# ifdef _MPI_DBG
  REPORT::rpt.Output( " (PRECO_ILUT::Solve)     starting with 1.2\n" );
# endif

# ifdef _MPI_

  if( project->subdom.npr > 1 )
  {
    SUBDOM* subdom = &project->subdom;
    INFACE* inface = subdom->inface;

    MPI_Status status;

    int df = eqs->dfcn;

    for( int s=subdom->npr-1; s>=0; s-- )
    {
      int np = inface[s].np;                      // number of interface nodes

      if( np > 0  &&  s < subdom->pid )           // upstream interface nodes
      {
        int cnt = 0;

#       ifdef _MPI_DBG
        {
          char text[200];
          sprintf( text, " ### receiving from %d:", s+1 );
          REPORT::rpt.Output( text );
        }
#       endif

        MPI_Recv( &cnt, 1, MPI_INT, s, 1, MPI_COMM_WORLD, &status );

#       ifdef _MPI_DBG
        {
          char text[200];
          sprintf( text, " %d values\n", cnt );
          REPORT::rpt.Output( text );
        }
#       endif

        if( cnt )
        {
          MPI_Recv( inface[s].recv, cnt, MPI_DOUBLE, s, 2, MPI_COMM_WORLD, &status );

          cnt = 0;

          for( int n=0; n<np; n++ )
          {
            NODE* nd = inface[s].node[n];

            if( !isFS(nd->flag, NODE::kDry) )       // nothing received if node is dry...
            {
              SUB* sub = nd->sub;
              while( sub )
              {
                if( sub->no == s )  break;
                sub = sub->next;
              }

              if( !sub->dry )                       // ...or if the node is dry in
              {                                     // any adjacent subdomain
                for( int e=0; e<df; e++ )
                {
                  int eqno = eqs->GetEqno( nd, e );

                  if( eqno >= 0 )
                  {
                    X[eqno] = inface[s].recv[cnt];
                    cnt++;
                  }
                }
              }
            }
          }
        }
      }
    }
  }


  ////////////////////////////////////////////////////////////////////////////////////////
  // 1.3 MPI: forward solve for upstream interface nodes
  //          Note: X[i] is not initialized with B[i] since
  //                this was performed in prior subdomain

# ifdef _MPI_DBG
  REPORT::rpt.Output( " (PRECO_ILUT::Solve)     starting with 1.3\n" );
# endif

  for( int i=neq_up; i<neq_dn; i++ )
  {
    for( int j=1; j<width[i]; j++ )
    {
      int eq = index[i][j];

      if( eq < i )
      {
        X[i] += ILU[i][j] * X[eq];
      }
    }
  }


  ////////////////////////////////////////////////////////////////////////////////////////
  // 1.4 MPI: faktorisation of downstream interface nodes

# ifdef _MPI_DBG
  REPORT::rpt.Output( " (PRECO_ILUT::Solve)     starting with 1.4\n" );
# endif

  for( int i=neq_dn; i<neq; i++ )
  {
    X[i] = B[i];

    for( int j=1; j<width[i]; j++ )
    {
      int eq = index[i][j];

      if( eq < neq_dn )
      {
        X[i] += ILU[i][j] * X[eq];
      }
    }
  }


  ////////////////////////////////////////////////////////////////////////////////////////
  // 1.5 MPI communication:
  //     send to subdomains with larger pid        (2 -> 3)
  //     s > pid  ==> downstream interface nodes

# ifdef _MPI_DBG
  REPORT::rpt.Output( " (PRECO_ILUT::Solve)     starting with 1.5\n" );
# endif

  if( project->subdom.npr > 1 )
  {
    SUBDOM* subdom = &project->subdom;
    INFACE* inface = subdom->inface;

    int df = eqs->dfcn;

    for( int s=0; s<subdom->npr; s++ )
    {
      int np = inface[s].np;                      // number of interface nodes

      if( np > 0  &&  s > subdom->pid )           // downstream interface nodes
      {
        int cnt = 0;

        for( int n=0; n<np; n++ )
        {
          NODE* nd = inface[s].node[n];

          if( !isFS(nd->flag, NODE::kDry) )       // nothing to send if the node is dry...
          {
            SUB* sub = nd->sub;
            while( sub )
            {
              if( sub->no == s )  break;
              sub = sub->next;
            }

            if( !sub->dry )                       // ...or if the node is dry in
            {                                     // any adjacent subdomain
              for( int e=0; e<df; e++ )
              {
                int eqno = eqs->GetEqno( nd, e );

                if( eqno >= 0 )
                {
                  inface[s].send[cnt] = X[eqno];
                  cnt++;
                }
              }
            }
          }
        }

#       ifdef _MPI_DBG
        {
          char text[200];
          sprintf( text, " ### sending %d values to %d\n", cnt, s+1 );
          REPORT::rpt.Output( text );
        }
#       endif

        MPI_Send( &cnt, 1, MPI_INT, s, 1, MPI_COMM_WORLD );
        if( cnt ) MPI_Send( inface[s].send, cnt, MPI_DOUBLE, s, 2, MPI_COMM_WORLD );
      }
    }
  }

# endif
  ////////////////////////////////////////////////////////////////////////////////////////

# ifdef kDebug
  {
    FILE* dbg;
    char  filename[80];

    MODEL* model  = project->M2D;
    GRID*  region = model->region;

    if( project->subdom.npr == 1 )
      sprintf( filename, "forwX.dbg" );
    else
      sprintf( filename, "forwX_%02d.dbg", project->subdom.pid );

    dbg = fopen( filename, "w" );
    fprintf( dbg, "%d\n", region->Getnp() );

    for( int n=0; n<region->Getnp(); n++ )
    {
      NODE* nd = region->Getnode( n );
      for( int e=0; e<eqs->dfcn; e++ )
      {
        int eqno = eqs->GetEqno( nd, e );
        fprintf( dbg, "%5d %1d ", nd->Getname(), e );
        if( eqno >= 0 )
          fprintf( dbg, "%14.6le\n", X[eqno] );
        else
          fprintf( dbg, "%14.6le\n", 0.0 );
      }
    }

    fclose( dbg );
  }
# endif

# ifdef _MPI_DBG
  REPORT::rpt.Output( " (PRECO_ILUT::Solve)     forward solve finished\n" );
# endif

  ////////////////////////////////////////////////////////////////////////////////////////
  // 2.  solve for X with upper part of matrix ILU (backward substitution)
  //
  // 2.1 MPI communication:
  //     receive from subdomains with larger pid    (2 <- 3)
  //     s > pid  ==> downstream interface nodes

# ifdef _MPI_DBG
  REPORT::rpt.Output( " (PRECO_ILUT::Solve)     starting with 2.1\n" );
# endif

# ifdef _MPI_

  if( project->subdom.npr > 1 )
  {
    SUBDOM* subdom = &project->subdom;
    INFACE* inface = subdom->inface;

    MPI_Status status;

    int df = eqs->dfcn;

    for( int s=subdom->npr-1; s>=0; s-- )
    {
      int np = inface[s].np;                // number of interface nodes

      if( np > 0  &&  s > subdom->pid )     // downstream interface nodes
      {
        int cnt = 0;

#       ifdef _MPI_DBG
        {
          char text[200];
          sprintf( text, " ### receiving from %d:", s+1 );
          REPORT::rpt.Output( text );
        }
#       endif

        MPI_Recv( &cnt, 1, MPI_INT, s, 1, MPI_COMM_WORLD, &status );

#       ifdef _MPI_DBG
        {
          char text[200];
          sprintf( text, " %d values\n", cnt );
          REPORT::rpt.Output( text );
        }
#       endif

        if( cnt )
        {
          MPI_Recv( inface[s].recv, cnt, MPI_DOUBLE, s, 2, MPI_COMM_WORLD, &status );

          cnt = 0;

          for( int n=0; n<np; n++ )
          {
            NODE* nd = inface[s].node[n];

            if( !isFS(nd->flag, NODE::kDry) )       // nothing received if node is dry...
            {
              SUB* sub = nd->sub;
              while( sub )
              {
                if( sub->no == s )  break;
                sub = sub->next;
              }

              if( !sub->dry )                       // ...or if the node is dry in
              {                                     // any adjacent subdomain
                for( int e=0; e<df; e++ )
                {
                  int req = eqs->GetEqno( nd, e );

                  if( req >= 0 )
                  {
                    X[req] = inface[s].recv[cnt];
                    cnt++;
                  }
                }
              }
            }
          }
        }
      }
    }
  }


  ////////////////////////////////////////////////////////////////////////////////////////
  // 2.2 MPI: solve for upstream interface nodes

# ifdef _MPI_DBG
  REPORT::rpt.Output( " (PRECO_ILUT::Solve)     starting with 2.2\n" );
# endif

  for( int i=neq_dn-1; i>=neq_up; i-- )
  {
    for( int j=1; j<width[i]; j++ )
    {
      int eq = index[i][j];

      if( eq > i )
      {
        X[i] -= ILU[i][j] * X[eq];
      }
    }

    if( fabs(ILU[i][0]) < kZero )
      REPORT::rpt.Error( kParameterFault, "division by zero - EQS::ILU_solver(1)" );

    X[i] /= ILU[i][0];
  }


  ////////////////////////////////////////////////////////////////////////////////////////
  // 2.3 MPI communication:
  //     send to subdomains with smaller pid        (2 -> 1)
  //     s < pid  ==> upstream interface nodes

# ifdef _MPI_DBG
  REPORT::rpt.Output( " (PRECO_ILUT::Solve)     starting with 2.3\n" );
# endif

  if( project->subdom.npr > 1 )
  {
    SUBDOM* subdom = &project->subdom;
    INFACE* inface = subdom->inface;

    int df = eqs->dfcn;

    for( int s=0; s<subdom->npr; s++ )
    {
      int np = inface[s].np;                      // number of interface nodes

      if( np > 0  &&  s < subdom->pid )           // upstream interface nodes
      {
        int cnt = 0;

        for( int n=0; n<np; n++ )
        {
          NODE* nd = inface[s].node[n];

          if( !isFS(nd->flag, NODE::kDry) )       // nothing to send if node is dry...
          {
            SUB* sub = nd->sub;
            while( sub )
            {
              if( sub->no == s )  break;
              sub = sub->next;
            }

            if( !sub->dry )                       // ...or if the node is dry in
            {                                     // any adjacent subdomain
              for( int e=0; e<df; e++ )
              {
                int eqno = eqs->GetEqno( nd, e );

                if( eqno >= 0 )
                {
                  inface[s].send[cnt] = X[eqno];
                  cnt++;
                }
              }
            }
          }
        }

#       ifdef _MPI_DBG
        {
          char text[200];
          sprintf( text, " ### sending %d values to %d\n", cnt, s+1 );
          REPORT::rpt.Output( text );
        }
#       endif

        MPI_Send( &cnt, 1, MPI_INT, s, 1, MPI_COMM_WORLD );
        if( cnt )  MPI_Send( inface[s].send, cnt, MPI_DOUBLE, s, 2, MPI_COMM_WORLD );
      }
    }
  }

# endif
  ////////////////////////////////////////////////////////////////////////////////////////

  ////////////////////////////////////////////////////////////////////////////////////////
  // 2.4 MPI: backward solve for interior nodes

# ifdef _MPI_DBG
  REPORT::rpt.Output( " (PRECO_ILUT::Solve)     starting with 2.4\n" );
# endif

  for( int i=neq_up-1; i>=0; i-- )
  {
    for( int j=1; j<width[i]; j++ )
    {
      int eq = index[i][j];

      if( eq > i )
      {
        X[i] -= ILU[i][j] * X[eq];
      }
    }

    if( fabs(ILU[i][0]) < kZero )
      REPORT::rpt.Error( kParameterFault, "division by zero - EQS::ILU_solver(2)" );

    X[i] /= ILU[i][0];
  }

# ifdef kDebug
  {
    FILE* dbg;
    char  filename[80];

    MODEL* model  = project->M2D;
    GRID*  region = model->region;

    if( project->subdom.npr == 1 )
      sprintf( filename, "backX.dbg" );
    else
      sprintf( filename, "backX_%02d.dbg", project->subdom.pid );

    dbg = fopen( filename, "w" );
    fprintf( dbg, "%d\n", region->Getnp() );

    for( int n=0; n<region->Getnp(); n++ )
    {
      NODE* nd = region->Getnode( n );
      for( int e=0; e<eqs->dfcn; e++ )
      {
        fprintf( dbg, "%5d %1d ", nd->Getname(), e );

        int eqno = eqs->GetEqno( nd, e );

        if( eqno >= 0 )
          fprintf( dbg, "%14.6le\n", X[eqno] );
        else
          fprintf( dbg, "%14.6le\n", 0.0 );
      }
    }

    fclose( dbg );
  }

  MPI_Barrier( MPI_COMM_WORLD );

# endif

# ifdef _MPI_DBG
  REPORT::rpt.Output( " (PRECO_ILUT::Solve)     backward solve finished\n" );
# endif
}
コード例 #23
0
int countQueen(GRID g, int n, int x, int y, const VVV& ava, VVB pos, MAP& hash)
{
     if (n == 0)
	  return 1;
     int count = 0;     
     if (g[x][y] != '.')
     {
	  y ++;
	  if (y == g[0].size())
	  {
	       y = 0;
	       x ++;
	  }
	  if(x == g.size())
	       return count;	  
	  count += countQueen(g, n, x, y, ava, pos, hash);
	  count %= 1000000007;
	  return count;
     }

     Key key;
     key.status = pos;
     key.n = n;
     MAP::iterator iter = hash.find(key);
     if(iter != hash.end())
     {
	  assert(key.n == iter->first.n);
	  return iter->second;
     }
     
     if(pos[x][y])
     {
	  if(validate(g, x, y, ava))
	  {
	       GRID cp(g);
	       VVB cpb(pos);	       
	       cp[x][y] = 'q';
	       resetPos(g, x, y, cpb);
	       int r = countQueen(cp, n - 1, x, y, ava, cpb, hash);
	       	       
	       count += r; //countQueen(cp, n - 1, x, y, ava, cpb, hash);
	       count %= 1000000007;

	  }
     }
     pos[x][y] = false;
     bool record = (g[x][y] == '.');

     y ++;
     if (y == g[0].size())
     {
	  y = 0;
	  x ++;
     }
     if(x == g.size())
	  return count;
     count += countQueen(g, n, x, y, ava, pos, hash);
     count %= 1000000007;
     if (record)
	  hash[key] = count;
     
     return count;
}
コード例 #24
0
void resetPos(const GRID & g, int i, int j, VVB& pos)
{
     int x, y;
     //down check
     x = i, y = j;
     while(x < g.size() && g[x][y] != '#')
     {
	  pos[x][y]=false;	  
	  --x;
     }
     
     //left check
     x = i, y = j;
     while(y < g[0].size() && g[x][y] != '#')
     {
	  pos[x][y]=false;	  	  
	  --y;
     }

     //up left check
     x = i, y = j;
     while(x >= 0 && y >= 0 && x < g.size() && y < g[0].size() && g[x][y] != '#')
     {
	  pos[x][y]=false;	  	  
	  --x, --y;
     }
     
     //up right check
     x = i, y = j;
     while(x >= 0 && y >= 0 && x < g.size() && y < g[0].size() && g[x][y] != '#')
     {

	  pos[x][y]=false;	  	  
	  --x, ++y;
     }
     
     //down check
     x = i, y = j;
     while(x < g.size() && g[x][y] != '#')
     {

	  pos[x][y]=false;	  
	  ++x;
     }
     
     //right check
     x = i, y = j;
     while(y < g[0].size() && g[x][y] != '#')
     {

	  pos[x][y]=false;	  	  
	  ++y;
     }

     //down left check
     x = i, y = j;
     while(x >= 0 && y >= 0 && x < g.size() && y < g[0].size() && g[x][y] != '#')
     {

	  pos[x][y]=false;	  	  
	  ++x, --y;
     }
     
     //down right check
     x = i, y = j;
     while(x >= 0 && y >= 0 && x < g.size() && y < g[0].size() && g[x][y] != '#')
     {

	  pos[x][y]=false;	  
	  ++x, ++y;
     }     
}
コード例 #25
0
int main(int narg, char **args)
{
  GRID grid;
  EM_FIELD myfield;
  CURRENT current;
  std::vector<SPECIE*> species;
  std::vector<SPECIE*>::const_iterator spec_iterator;
  gsl_rng* rng = gsl_rng_alloc(gsl_rng_ranlxd1);

  //*******************************************BEGIN GRID DEFINITION*******************************************************

  grid.setXrange(-50.0, 0.0);
  grid.setYrange(-15.0, 15.0);
  grid.setZrange(-1, +1);

  grid.setNCells(1536, 512, 1);
  grid.setNProcsAlongY(NPROC_ALONG_Y);
  grid.setNProcsAlongZ(NPROC_ALONG_Z);

  //grid.enableStretchedGrid();
  //grid.setXandNxLeftStretchedGrid(-20.0,1000);
  //grid.setYandNyLeftStretchedGrid(-8.0,21);
  //grid.setXandNxRightStretchedGrid(20.0,1000);
  //grid.setYandNyRightStretchedGrid(8.0,21);

  grid.setBoundaries(xOpen | yPBC | zPBC);
  grid.mpi_grid_initialize(&narg, args);
  grid.setCourantFactor(0.98);

  grid.setSimulationTime(100.0);

  grid.with_particles = YES;//NO;
  grid.with_current = YES;//YES;

  grid.setStartMovingWindow(0);
  //grid.setBetaMovingWindow(1.0);
  //grid.setFrequencyMovingWindow(20);

  grid.setMasterProc(0);

  srand(time(NULL));
  grid.initRNG(rng, RANDOM_NUMBER_GENERATOR_SEED);

  grid.finalize();

  grid.visualDiag();

  //********************************************END GRID DEFINITION********************************************************

  //*******************************************BEGIN FIELD DEFINITION*********************************************************
  myfield.allocate(&grid);
  myfield.setAllValuesToZero();

  laserPulse pulse1;
  pulse1.setGaussianPulse();
  pulse1.setWaist(4.0);
  pulse1.setDurationFWHM(10.0);
  pulse1.setNormalizedAmplitude(0.5);
  pulse1.setCircularPolarization();
  pulse1.setPulseInitialPosition(-10.1);
  pulse1.setFocusPosition(0.0);
  pulse1.setLambda(1.0);
  pulse1.setFocusPosition(0.0);
  //    pulse1.setRotationAngleAndCenter(2.0*M_PI*(-30.0 / 360.0), 0.0);
  myfield.addPulse(&pulse1);

  myfield.boundary_conditions();

  current.allocate(&grid);
  current.setAllValuesToZero();
  //*******************************************END FIELD DEFINITION***********************************************************

  //*******************************************BEGIN SPECIES DEFINITION*********************************************************
  PLASMA plasma1;
  plasma1.density_function = box;
  plasma1.setXRangeBox(0.0, 100.0);
  plasma1.setYRangeBox(grid.rmin[1], grid.rmax[1]);
  plasma1.setZRangeBox(grid.rmin[2], grid.rmax[2]);
  plasma1.setDensityCoefficient(0.0025);

  SPECIE  electrons1(&grid);
  electrons1.plasma = plasma1;
  electrons1.setParticlesPerCellXYZ(2, 2, 2);
  electrons1.setName("ELE1");
  electrons1.type = ELECTRON;
  electrons1.creation();
  species.push_back(&electrons1);


  SPECIE ions1(&grid);
  ions1.plasma = plasma1;
  ions1.setParticlesPerCellXYZ(2, 2, 2);
  ions1.setName("ION1");
  ions1.type = ION;
  ions1.Z = 6.0;
  ions1.A = 12.0;
  //ions1.creation();
  //species.push_back(&ions1);


  //tempDistrib distribution;
  //distribution.setWaterbag(1.0e-8);
  //electrons1.add_momenta(rng,0.0,0.0,0.0,distribution);
  //ions1.add_momenta(rng,0.0, 0.0, 0.0, distribution);

  for (spec_iterator = species.begin(); spec_iterator != species.end(); spec_iterator++){
    (*spec_iterator)->printParticleNumber();
  }

  //*******************************************END SPECIED DEFINITION***********************************************************

  //*******************************************BEGIN DIAGNOSTICS DEFINITION**************************************************
  OUTPUT_MANAGER manager(&grid, &myfield, &current, species);

  //    manager.addEBFieldFrom(0.0,10.0);
  //    manager.addSpeciesDensityFrom(electrons1.name, 0.0, 10.0);
  //    manager.addSpeciesPhaseSpaceFrom(electrons1.name, 0.0, 10.0);
  //    //manager.addSpeciesDensityFrom(ions1.name, 0.0, 1.0);
  //    manager.addDiagFrom(0.0, 1.0);

  manager.initialize(DIRECTORY_OUTPUT);
  //*******************************************END DIAGNOSTICS DEFINITION**************************************************
  grid.setDumpPath(DIRECTORY_DUMP);
  //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ MAIN CYCLE (DO NOT MODIFY!!) @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  if (grid.myid == grid.master_proc){
    printf("----- START temporal cicle -----\n");
    fflush(stdout);
  }

  int Nstep = grid.getTotalNumberOfTimesteps();
  int dumpID = 1, dumpEvery;
  if (DO_DUMP){
    dumpEvery = (int)(TIME_BTW_DUMP / grid.dt);
  }
  grid.istep = 0;
  if (_DO_RESTART){
    dumpID = _RESTART_FROM_DUMP;
    restartFromDump(&dumpID, &grid, &myfield, species);
  }
  while (grid.istep <= Nstep)
  {

    grid.printTStepEvery(FREQUENCY_STDOUT_STATUS);

    manager.callDiags(grid.istep);

    myfield.openBoundariesE_1();
    myfield.new_halfadvance_B();
    myfield.boundary_conditions();

    current.setAllValuesToZero();
    for (spec_iterator = species.begin(); spec_iterator != species.end(); spec_iterator++){
      (*spec_iterator)->current_deposition_standard(&current);
    }
    current.pbc();

    for (spec_iterator = species.begin(); spec_iterator != species.end(); spec_iterator++){
      (*spec_iterator)->position_parallel_pbc();
    }

    myfield.openBoundariesB();
    myfield.new_advance_E(&current);

    myfield.boundary_conditions();
    myfield.openBoundariesE_2();
    myfield.new_halfadvance_B();
    myfield.boundary_conditions();

    for (spec_iterator = species.begin(); spec_iterator != species.end(); spec_iterator++){
      (*spec_iterator)->momenta_advance(&myfield);
    }

    grid.time += grid.dt;

    moveWindow(&grid, &myfield, species);

    grid.istep++;
    if (DO_DUMP){
      if (grid.istep != 0 && !(grid.istep % (dumpEvery))) {
        dumpFilesForRestart(&dumpID, &grid, &myfield, species);
      }
    }
  }

  manager.close();
  MPI_Finalize();
  exit(1);

}
コード例 #26
0
ファイル: Start.cpp プロジェクト: dan-phd/2DTDBEM
void run_Zmatrices_calculation_scattered_field(Zmatrices& Z_matrices, UINT Lagrange_degree,
	MATRIX M, MATRIX J, GRID& rho, double material_param, const char* result_file)
{
	// Simulation parameters
	int N_T = Z_matrices.z_N_T;
	double dt = Z_matrices.z_dt;
	double c = Z_matrices.z_c;
	UINT inner_points = 1;
	printf("\nSimulation parameters for scattered field:"
		"\n\tNumber of grid vertices = %i"
		"\n\tMaterial parameter = %e"
		"\n\tc = %e"
		"\n\tdt = %e"
		"\n\tN_T = %i"
		"\n\tinner_points = %i"
		"\n\tLagrange_degree = %i\n\n",
		(int)rho.size(), material_param, c, dt, N_T, inner_points, Lagrange_degree);

	// Lagrange interpolators (temporal basis functions)
	CLagrange_interp timeBasis = CLagrange_interp(dt, Lagrange_degree);
	Z_matrices.timeBasis_D = timeBasis;
	CLagrange_interp timeBasis_Ns = timeBasis;
	timeBasis_Ns.diff();
	Z_matrices.timeBasis_Ns = timeBasis_Ns;

	Z_matrices.z_inner_points = inner_points;

	// do main computation
	cube S, D;
#ifdef OS_WIN
	clock_t t;
#else
	struct timeval * t = new struct timeval;
#endif
	start_timing(t);
	Z_matrices.compute_fields(S, D, rho);
	S *= material_param;
	finish_timing(t);

	start_timing(t);
	MATRIX rhs(D.n_rows, N_T, fill::zeros);
	VECTOR rhs_(D.n_rows, fill::zeros);
	printf("%s\n\n", "Marching on in time...");
	int j(0), k(0);
//#pragma omp parallel default(shared) private(j,k)
	for (j = 0; j < N_T; j++)
	{
//#pragma omp for
		for (k = 0; k < j+1; k++)
		{
			rhs_ += D.slice(k)*M.col(j - k) - S.slice(k)*J.col(j - k);
		}

		rhs.col(j) = rhs_;
		rhs_.zeros();

		//Status
		printf("\r%i ", j + 1);
		fflush(stdout);
	}

	finish_timing(t);

	// Output MAT file that stores the operators
	printf("Compressing matrices into Matlab form...");
	mat_t *matfpZ = NULL;
	matvar_t *matvar = NULL;

	// Save matrices as separate matlab variables
	if (CreateMatFile(&matfpZ, result_file) == -1)
	{
		return;
	}
	else
	{
		double NT = (double)N_T;
		InsertVar(&matfpZ, "N_T", &NT);
		InsertMatrix(&matfpZ, "E", rhs);
		FinishMatFile(&matfpZ);

		// free memory
		S.clear(), D.clear();

		printf("\t- done.\nOutput file location: %s\n\n", result_file);
	}
}
コード例 #27
0
ファイル: EqsKD2D.cpp プロジェクト: markuszi/Rismo2D
void EQS_KD2D::Execute( PROJECT* project, int steadyFlow, int shape )
{
  switch( shape )
  {
    case 0:
      linearShape  = false;
      quarterShape = false;
      break;
    case 1:
      linearShape  = true;
      quarterShape = false;
      break;
    case 2:
      linearShape  = false;
      quarterShape = true;
      break;
  }

  MODEL* model    = project->M2D;
  GRID*  rg       = project->M2D->region;

  NODE** node     = model->node;
  ELEM** elem     = model->elem;

  int np          = model->np;
  int ne          = model->ne;

  int diverged_cg = 0;

  double* B    = NULL;
  double* xKD  = NULL;
  double* xKDo = NULL;
  double* cxKo = NULL;
  double* cxDo = NULL;

  model->Incinit();

  // print information on actual iteration -----------------------------------------------
  project->PrintTheCycle( 1 );
  REPORT::rpt.PrintTime( 1 );

  // set parameters according to time integration and relaxation -------------------------
  double th = project->timeint.thetaTurb;
  double dt = project->timeint.incTime.Getsec();

  if( fabs(th) < 1.0e-10  &&  fabs(dt) < 1.0e-10 )
  {
    REPORT::rpt.Error( kParameterFault,
                       "theta and timeInterval too small (EQS_KD2D::execute - 1)" );
  }

  double thdt = 1.0 / dt / th;

  double dt_KD;
  double relaxDt_KD = project->timeint.relaxTimeTurb.Getsec();

  int relaxMethod = project->relaxMethod;


  if( steadyFlow )
  {
    if( relaxMethod >= 3 )
    {
      dt_KD = relaxDt_KD;
      relaxThdt_KD = 1.0 / dt_KD;
    }
    else
    {
      dt_KD = dt;
      relaxThdt_KD = 0.0;
    }

    for( int i=0; i<np; i++ )
    {
      node[i]->v.dKdt = 0.0;
      node[i]->v.dDdt = 0.0;
    }
  }
  else
  {
    if( relaxMethod >= 3 )
    {
      dt_KD = relaxDt_KD;
    }
    else
    {
      dt_KD = dt;
    }

    relaxThdt_KD = 1.0 / dt_KD / th;

    // time prediction -------------------------------------------------------------------
    for( int i=0; i<np; i++ )
    {
      VARS* v = &(node[i]->v);

      //VARS* vo = &(node[i]->vo);

      //v->K = vo->K  +  vo->dKdt * dt;
      //v->D = vo->D  +  vo->dDdt * dt;

      //v->dKdt = (1.0 - 1.0/th)*vo->dKdt + thdt*(v->K - vo->K);
      //v->dDdt = (1.0 - 1.0/th)*vo->dDdt + thdt*(v->D - vo->D);

      v->dKdt = 0.0;
      v->dDdt = 0.0;
    }
  }

  // check KD-values for validity (>= 0) -------------------------------------------------
  Validate( project, np, node );

  // determine friction coefficients -----------------------------------------------------
  model->DoFriction( project );

  // initialize Reynolds stresses and eddy viscosity -------------------------------------
  rg->Turbulence( project );

  // set KD boundary conditions ----------------------------------------------------------
  model->SetBoundKD( project );

  // -------------------------------------------------------------------------------------
  // in case of quartered elements:
  // compute averaged values of U, V, S, K and D for the virtual center node in quads

  int     nq   = 0;
  double* cxK  = NULL;
  double* cxD  = NULL;

  if( quarterShape )
  {
    // count number of quadrilaterals
    for( int e=0; e<ne; e++ )
    {
      if( elem[e]->Getncn() == 4 )  nq++;
    }

    // allocate memory for nq center nodes
    if( !cbuf )  cbuf = new NODE [nq];
    if( !cbuf )
    {
      REPORT::rpt.Error( kMemoryFault, "cannot allocate memory (EQS_KD2D::execute - 2)" );
    }

    cent = (NODE**)  MEMORY::memo.Array_el( ne );
    cxK  = (double*) MEMORY::memo.Array_el( ne );
    cxD  = (double*) MEMORY::memo.Array_el( ne );

    nq = 0;
    for( int e=0; e<ne; e++ )
    {
      ELEM* el  = elem[e];

      if( isFS(el->flag, ELEM::kRegion) )
      {
        int  no  = el->Getno();
        int  ncn = el->Getncn();

        cent[no] = NULL;

        if( ncn == 4 )
        {
          cent[no] = &cbuf[nq++];

          cent[no]->Setno( no );

          cent[no]->x      = 0.0;
          cent[no]->y      = 0.0;
          cent[no]->z      = 0.0;
          cent[no]->cf     = 0.0;
          cent[no]->v.U    = 0.0;
          cent[no]->v.V    = 0.0;
          cent[no]->v.S    = 0.0;
          cent[no]->v.K    = 0.0;
          cent[no]->v.D    = 0.0;
          cent[no]->v.dKdt = 0.0;
          cent[no]->v.dDdt = 0.0;

          for( int i=0; i<ncn; i++ )
          {
            cent[no]->x      += el->nd[i]->x;
            cent[no]->y      += el->nd[i]->y;
            cent[no]->z      += el->nd[i]->z;
            cent[no]->cf     += el->nd[i]->cf;
            cent[no]->v.U    += el->nd[i]->v.U;
            cent[no]->v.V    += el->nd[i]->v.V;
            cent[no]->v.S    += el->nd[i]->v.S;
            cent[no]->v.K    += el->nd[i]->v.K;
            cent[no]->v.D    += el->nd[i]->v.D;
            cent[no]->v.dKdt += el->nd[i]->v.dKdt;
            cent[no]->v.dDdt += el->nd[i]->v.dDdt;
          }

          cent[no]->x      /= ncn;
          cent[no]->y      /= ncn;
          cent[no]->z      /= ncn;
          cent[no]->cf     /= ncn;
          cent[no]->v.U    /= ncn;
          cent[no]->v.V    /= ncn;
          cent[no]->v.S    /= ncn;
          cent[no]->v.K    /= ncn;
          cent[no]->v.D    /= ncn;
          cent[no]->v.dKdt /= ncn;
          cent[no]->v.dDdt /= ncn;
        }
      }
    }
  }


  // -------------------------------------------------------------------------------------
  // iteration loop

  double dt_KDo =  0.0;
  double relaxo =  1.0;
  double maxKDo = -1.0;

  int conv;

  for( int it=0; it<project->actualCycit; it++ )
  {
    conv = true;

    // print information on actual iteration ---------------------------------------------
    if( it > 0 )
    {
      project->PrintTheCycle( it+1 );
      REPORT::rpt.PrintTime( 1 );
    }

    // initialize Reynolds stresses and eddy viscosity -----------------------------------
    if( it > 0  &&  isFS(project->actualTurb, BCONSET::kVtIterat)
                && !isFS(project->actualTurb, BCONSET::kVtPrandtlKol) )
    {
      rg->Turbulence( project );
    }

    // set up equation numbers -----------------------------------------------------------
    if( model->Getinit() != modelInit )
    {
      initStructure = true;
      modelInit = model->Getinit();

      project->fix[0] = BCON::kFixK;
      project->fix[1] = BCON::kFixD;

      project->elemKind = ELEM::kRegion;

      if( linearShape )
      {
        SetEqno( model, 2, 0, 0, project->fix, project->elemKind );
      }
      else
      {
        SetEqno( model, 2, 2, 0, project->fix, project->elemKind );
      }

      if( B )   MEMORY::memo.Detach( B );
      if( xKD ) MEMORY::memo.Detach( xKD );

      B   = (double*) MEMORY::memo.Array_eq( neq );
      xKD = (double*) MEMORY::memo.Array_eq( neq );

      // allocate memory for relaxed Newton-Rahpson
      if( relaxMethod >= 3 )
      {
        xKDo = (double*) MEMORY::memo.Array_eq( neq );

        if( quarterShape )
        {
          cxKo = (double*) MEMORY::memo.Array_el( ne );
          cxDo = (double*) MEMORY::memo.Array_el( ne );
        }
      }
    }

    // solve equations with frontal solving algorithm ------------------------------------
    for( int i=0; i<neq; i++ )  xKD[i] = 0.0;

    diverged_cg = Solve( model, neq, B, xKD, project );


    // -----------------------------------------------------------------------------------
    // determine new values for K and D at virtual center nodes

    if( quarterShape )
    {
      for( int e=0; e<ne; e++ )
      {
        ELEM* el = elem[e];

        if( isFS(el->flag, ELEM::kRegion) )
        {
          int  no  = el->Getno();
          int  ncn = el->Getncn();

          if( ncn == 4 )
          {
            Coefs( el, project, estifm, force );

            cxK[no] = force[16];
            cxD[no] = force[17];

            for( int i=0; i<8; i++ )
            {
              int eqK = GetEqno( el->nd[i], 0 );
              int eqD = GetEqno( el->nd[i], 1 );

              cxK[no] -= estifm[16][i] * xKD[eqK] + estifm[16][i+8] * xKD[eqD];
              cxD[no] -= estifm[17][i] * xKD[eqK] + estifm[17][i+8] * xKD[eqD];
            }

            cxK[no] /= estifm[16][16];

            cxD[no] -= estifm[17][16] * cxK[no];
            cxD[no] /= estifm[17][17];
          }
        }
      }
    }


    // -----------------------------------------------------------------------------------
    // statistics

    REPORT::rpt.Message( 2, "\n\n%-25s%s\n\n %s\n\n",
                            " (EQS_KD2D::Execute)", "convergence parameters ...",
                            " variable   node          average        maximum" );


    // compute averaged changes and standard deviation of K and D ------------------------

    double stdevK  = 0.0;
    double stdevD  = 0.0;

    double aveAbsK = 0.0;
    double aveAbsD = 0.0;

    for( int i=0; i<np; i++ )
    {
      int eqno;

      double dK = 0.0;
      double dD = 0.0;

      eqno = GetEqno( node[i], 0 );
      if( eqno >= 0 )  dK = xKD[eqno];

      eqno = GetEqno( node[i], 1 );
      if( eqno >= 0 )  dD = xKD[eqno];

      aveAbsK += dK;
      stdevK  += dK*dK;

      aveAbsD += dD;
      stdevD  += dD*dD;
    }

    if( quarterShape )
    {
      for( int e=0; e<ne; e++ )
      {
        ELEM* el = elem[e];

        if( isFS(el->flag, ELEM::kRegion) )
        {
          int  no  = el->Getno();
          int  ncn = el->Getncn();

          if( ncn == 4 )
          {
            double dK = cxK[no];
            double dD = cxD[no];

            aveAbsK += dK;
            stdevK  += dK*dK;

            aveAbsD += dD;
            stdevD  += dD*dD;
          }
        }
      }
    }


    // -----------------------------------------------------------------------------------

    int nptot = 0;

    for( int i=0; i<np; i++ )
    {
      NODE* nd = rg->Getnode(i);
      if( !isFS(nd->flag, NODE::kInface_DN) )  nptot++;
    }

    //////////////////////////////////////////////////////////////////////////////////////
    // MPI: broadcast statistic
#   ifdef _MPI_
    aveAbsK = project->subdom.Mpi_sum( aveAbsK );
    stdevK  = project->subdom.Mpi_sum( stdevK );

    aveAbsD = project->subdom.Mpi_sum( aveAbsD );
    stdevD  = project->subdom.Mpi_sum( stdevD );

    nptot   = project->subdom.Mpi_sum( nptot );
#   endif
    //////////////////////////////////////////////////////////////////////////////////////

    aveAbsK /= nptot;
    stdevK   = sqrt( stdevK / nptot );

    aveAbsD /= nptot;
    stdevD   = sqrt( stdevD / nptot );

    double norm = stdevK + stdevD;

    double fractK = 2.0 * sqrt( stdevK );
    double fractD = 2.0 * sqrt( stdevD );


    // compute maximum changes of K and D limited to ~95% fractile -----------------------

    int    cntK    = 0;
    int    cntD    = 0;

    int    noPerK  = 0;
    double avePerK = 0.0;
    double maxPerK = 0.0;

    int    noAbsK  = 0;
    double maxAbsK = 0.0;

    int    noPerD  = 0;
    double avePerD = 0.0;
    double maxPerD = 0.0;

    int    noAbsD  = 0;
    double maxAbsD = 0.0;

    for( int i=0; i<np; i++ )
    {
      int eqno;
      double dK = 0.0;
      double dD = 0.0;

      eqno = GetEqno( node[i], 0 );
      if( eqno >= 0 )
      {
        dK = xKD[eqno];
        if( fabs(dK) > project->maxDeltaKD  &&  fabs(dK) > fractK )
        {
          xKD[eqno] = dK/fabs(dK) * fractK;
        }
      }

      eqno = GetEqno( node[i], 1 );
      if( eqno >= 0 )
      {
        dD = xKD[eqno];
        if( fabs(dD) > project->maxDeltaKD  &&  fabs(dD) > fractD )
        {
          xKD[eqno] = dD/fabs(dD) * fractD;
        }
      }

      // maximum changes and percentage
      if( node[i]->v.K + dK > 0.0 )
      {
        if( fabs(dK) > fabs(maxAbsK) )
        {
          maxAbsK = dK;
          noAbsK = node[i]->Getname();
        }

        if( node[i]->v.K > 0.0 )
        {
          double per = dK / node[i]->v.K;

          avePerK += fabs(per);
          cntK++;

          if( fabs(per) > fabs(maxPerK) )
          {
            maxPerK = per;
            noPerK = node[i]->Getname();
          }
        }
      }

      if( node[i]->v.D + dD > 0.0 )
      {
        if( fabs(dD) > fabs(maxAbsD) )
        {
          maxAbsD = dD;
          noAbsD = node[i]->Getname();
        }

        if( node[i]->v.D > 0.0 )
        {
          double per = dD / node[i]->v.D;

          avePerD += fabs(per);
          cntD++;

          if( fabs(per) > fabs(maxPerD) )
          {
            maxPerD = per;
            noPerD = node[i]->Getname();
          }
        }
      }
    }

    if( quarterShape )
    {
      for( int e=0; e<ne; e++ )
      {
        ELEM* el = elem[e];

        if( isFS(el->flag, ELEM::kRegion) )
        {
          int  no  = el->Getno();
          int  ncn = el->Getncn();

          if( ncn == 4 )
          {
            double dK = cxK[no];
            double dD = cxD[no];

            if( fabs(dK) > project->maxDeltaKD  &&  fabs(dK) > fractK )
            {
              cxK[no] = dK/fabs(dK) * fractK;
            }

            if( fabs(dD) > project->maxDeltaKD  &&  fabs(dD) > fractD )
            {
              cxD[no] = dD/fabs(dD) * fractD;
            }

            // maximum changes and percentage
            if( cent[no]->v.K + dK > 0.0 )
            {
              if( fabs(dK) > fabs(maxAbsK) )
              {
                maxAbsK = dK;
                noAbsK  = -(no+1);
              }

              if( cent[no]->v.K > 0.0 )
              {
                double per = dK / cent[no]->v.K;

                avePerK += fabs(per);
                cntK++;

                if( fabs(per) > fabs(maxPerK) )
                {
                  maxPerK = per;
                  noPerK  = -(no+1);
                }
              }
            }

            if( cent[no]->v.D + dD > 0.0 )
            {
              if( fabs(dD) > fabs(maxAbsD) )
              {
                maxAbsD = dD;
                noAbsD  = -(no+1);
              }

              if( cent[no]->v.D > 0.0 )
              {
                double per = dD / cent[no]->v.D;

                avePerD += fabs(per);
                cntD++;

                if( fabs(per) > fabs(maxPerD) )
                {
                  maxPerD = per;
                  noPerD  = -(no+1);
                }
              }
            }
          }
        }
      }
    }

    //////////////////////////////////////////////////////////////////////////////////////
    // MPI: broadcast statistic
#   ifdef _MPI_
    cntK    = project->subdom.Mpi_sum( cntK );
    maxAbsK = project->subdom.Mpi_maxabs( maxAbsK );
    avePerK = project->subdom.Mpi_sum( avePerK );
    maxPerK = project->subdom.Mpi_maxabs( maxPerK );

    cntD    = project->subdom.Mpi_sum( cntD );
    maxAbsD = project->subdom.Mpi_maxabs( maxAbsD );
    avePerD = project->subdom.Mpi_sum( avePerD );
    maxPerD = project->subdom.Mpi_maxabs( maxPerD );
#   endif
    //////////////////////////////////////////////////////////////////////////////////////

    avePerK /= cntK;
    avePerD /= cntD;

    REPORT::rpt.Message( 2, "      %1c     %5d       %12.5le   %12.5le %s\n",
                            'K', noAbsK+1, aveAbsK, maxAbsK, "     (abs)" );

    REPORT::rpt.Message( 2, "      %1c     %5d       %12.5lf   %12.5lf %s\n\n",
                            ' ', noPerK+1, avePerK, maxPerK, "     ( % )" );


    REPORT::rpt.Message( 2, "      %1c     %5d       %12.5le   %12.5le %s\n",
                            'D', noAbsD+1, aveAbsD, maxAbsD, "     (abs)" );

    REPORT::rpt.Message( 2, "      %1c     %5d       %12.5lf   %12.5lf %s\n\n",
                            ' ', noPerD+1, avePerD, maxPerD, "     ( % )" );


    if( fabs(maxAbsK) > project->convKD )  conv = false;
    if( fabs(maxAbsD) > project->convKD )  conv = false;


    // determine relaxation parameter for NEWTON-RAPHSON ---------------------------------

    double relax;

    double maxKD = fabs(maxAbsK);
    if( fabs(maxAbsD) > maxKD )  maxKD = fabs(maxAbsD);

    switch( relaxMethod )
    {
      default:
        REPORT::rpt.Warning( kParameterFault,
                             "relaxation method %d not supported", relaxMethod );

      case 0:
        relax = 1.0;

        REPORT::rpt.Message( 2, "\n%-25s%s %12.4le\n%-25s%s %12.4le\n\n",
                                " ", "relaxation (0): norm  =", norm,
                                " ", "                relax =", relax );
        break;

      case 2:
        relax = project->maxDeltaKD / maxKD;

        if( relax > 1.0 )  relax = 1.0;

        REPORT::rpt.Message( 2, "\n%-25s%s %12.4le\n%-25s%s %12.4le\n\n",
                                " ", "relaxation (2): norm  =", norm,
                                " ", "                relax =", relax );
        break;

      case 3:
        REPORT::rpt.Message( 2, "\n%-25s%s %12.4le\n",
                                " ", "relaxed time:   dt_KD =", dt_KD );

        if( dt_KD < dt )  conv = false;

        relax = project->maxDeltaKD / maxKD;

        dt_KD *= relax;

        if( dt_KD > dt )          dt_KD = dt;
        if( dt_KD < relaxDt_KD )  dt_KD = relaxDt_KD;

        if( steadyFlow ) relaxThdt_KD = 1.0 / dt_KD;
        else             relaxThdt_KD = 1.0 / dt_KD / th;

        if( relax > 1.0 )  relax = 1.0;

        REPORT::rpt.Message( 2, "\n%-25s%s %12.4le\n%-25s%s %12.4le\n\n",
                                " ", "relaxation (3): norm  =", norm,
                                " ", "                relax =", relax );
        break;

      case 4:
        REPORT::rpt.Message( 2, "\n%-25s%s %12.4le\n",
                                " ", "relaxed time:   dt_KD =", dt_KD );

        if( dt_KD < dt )  conv = false;

        relax = project->maxDeltaKD / maxKD;

        if( relax < project->relaxMax )
        {
          if( maxKDo < 0.0  ||  maxKD < maxKDo )  // initialisation: maxKDo = -1
          {
            if( relax < project->relaxMin ) relax = project->relaxMin;

            dt_KDo = dt_KD;
            maxKDo = maxKD;
          }
          else
          {
            if( relaxo > 1.01 * project->relaxMin )
            {
              // relaxed Newton-Raphson: restore K and D from previous iteration
              for( int i=0; i<np; i++ )
              {
                int n;
                n = GetEqno( node[i], 0 );
                if( n >= 0 )
                {
                  node[i]->v.K -= relaxo * xKDo[n];
                  xKD[n] = xKDo[n];
                }
                n = GetEqno( node[i], 1 );
                if( n >= 0 )
                {
                  node[i]->v.D -= relaxo * xKDo[n];
                  xKD[n] = xKDo[n];
                }
              }

              if( quarterShape )
              {
                for( int e=0; e<ne; e++ )
                {
                  ELEM* el = elem[e];

                  if( isFS(el->flag, ELEM::kRegion) )
                  {
                    if( el->Getncn() == 4 )
                    {
                      int no = el->Getno();
                      cent[no]->v.K -= relaxo * cxKo[no];
                      cent[no]->v.D -= relaxo * cxDo[no];
                      cxK[no] = cxKo[no];
                      cxD[no] = cxDo[no];
                    }
                  }
                }
              }
            }

            if( relax < project->relaxMin ) relax = project->relaxMin;

            dt_KDo = dt_KD;
            dt_KD *= relax;           // decrease dt_KD
            if( dt_KD < relaxDt_KD ) dt_KD = relaxDt_KD;

            maxKDo = maxKD;
          }
        }
        else
        {
          dt_KDo = dt_KD;

          if( relax > 1.0 ) dt_KD *= relax;       // increase dt_KD
          if( dt_KD > dt ) dt_KD = dt;

          relax  = 1.0;

          maxKDo = maxKD;

//          if( relax > relaxo )
//          {
//            relax = 0.1 * relaxo;

//            if( relax >= project->relaxMin )
//            {
//              // relaxed Newton-Raphson: restore K and D from previous iteration

//              for( int i=0; i<np; i++ )
//              {
//                int n;
//                n = GetEqno( node[i], 0 );
//                if( n >= 0 )
//                {
//                  node[i]->v.K -= relaxo * xKDo[n];
//                  xKD[n] = xKDo[n];
//                }
//                n = GetEqno( node[i], 1 );
//                if( n >= 0 )
//                {
//                  node[i]->v.D -= relaxo * xKDo[n];
//                  xKD[n] = xKDo[n];
//                }
//              }

//              if( quarterShape )
//              {
//                for( int e=0; e<ne; e++ )
//                {
//                  ELEM* el = elem[e];

//                  if( isFS(el->flag, ELEM::kRegion) )
//                  {
//                    if( el->Getncn() == 4 )
//                    {
//                      int no = el->Getno();
//                      cent[no]->v.K -= relaxo * cxKo[no];
//                      cent[no]->v.D -= relaxo * cxDo[no];
//                      cxK[no] = cxKo[no];
//                      cxD[no] = cxDo[no];
//                    }
//                  }
//                }
//              }

//              maxKDo = maxKD;
//            }
//            else
//            {
//              maxKDo = -1.0;
//            }
//          }
//          else
//          {
//            relax  = project->relaxMax;
//            maxKDo = maxKD;
//          }

//          if( relax > project->relaxMax )  relax = project->relaxMax;
//          if( relax < project->relaxMin )  relax = project->relaxMin;

//          if( relax < 0.999 * relaxo )  conv = false;
        }

        if( steadyFlow ) relaxThdt_KD = 1.0 / dt_KD;
        else             relaxThdt_KD = 1.0 / dt_KD / th;

        REPORT::rpt.Message( 2, "\n%-25s%s %12.4le\n%-25s%s %12.4le\n\n",
                                " ", "relaxation (4): norm  =", norm,
                                " ", "                relax =", relax );

        // relaxed Newton-Raphson: store xKD, cxK and cxD
        for( int i=0; i<np; i++ )
        {
          int n;
          n = GetEqno( node[i], 0 );
          if( n >= 0 )  xKDo[n] = xKD[n];

          n = GetEqno( node[i], 1 );
          if( n >= 0 )  xKDo[n] = xKD[n];
        }

        if( quarterShape )
        {
          for( int e=0; e<ne; e++ )
          {
            ELEM* el = elem[e];

            if( isFS(el->flag, ELEM::kRegion) )
            {
              if( el->Getncn() == 4 )
              {
                int no = el->Getno();
                cxKo[no] = cxK[no];
                cxDo[no] = cxD[no];
              }
            }
          }
        }
        break;
    }


    // update ----------------------------------------------------------------------------

    relaxo = relax;

    for( int i=0; i<np; i++ )
    {
      int n;
      n = GetEqno( node[i], 0 );
      if( n >= 0 )  node[i]->v.K += relax * xKD[n];

      n = GetEqno( node[i], 1 );
      if( n >= 0 )  node[i]->v.D += relax * xKD[n];
    }


    if( quarterShape )
    {
      for( int e=0; e<ne; e++ )
      {
        ELEM* el = elem[e];

        if( isFS(el->flag, ELEM::kRegion) )
        {
          if( el->Getncn() == 4 )
          {
            int no = el->Getno();
            cent[no]->v.K += relax * cxK[no];
            cent[no]->v.D += relax * cxD[no];
          }
        }
      }
    }


    // check for range of values ---------------------------------------------------------

    double minK = 0.0;
    double minD = 0.0;
    double maxK = 0.0;
    double maxD = 0.0;

    int first = true;

    int jk = 0;
    int jd = 0;

    for( int i=0; i<np; i++ )
    {
      if( first )
      {
        first = false;
        minK =
        maxK = node[i]->v.K;

        minD =
        maxD = node[i]->v.D;
      }
      else
      {
        if( node[i]->v.K < minK )  minK = node[i]->v.K;
        if( node[i]->v.K > maxK )  maxK = node[i]->v.K;

        if( node[i]->v.D < minD )  minD = node[i]->v.D;
        if( node[i]->v.D > maxD )  maxD = node[i]->v.D;
      }

      if( node[i]->v.K <= 0.0 )
      {
        if( GetEqno(node[i],0) >= 0 )  jk++;
      }

      if( node[i]->v.D <= 0.0 )
      {
        if( GetEqno(node[i],1) >= 0 )  jd++;
      }
    }

    //////////////////////////////////////////////////////////////////////////////////////
    // MPI: broadcast statistic
#   ifdef _MPI_
    jk   = project->subdom.Mpi_sum( jk );
    minK = project->subdom.Mpi_min( minK );
    maxK = project->subdom.Mpi_max( maxK );

    jd   = project->subdom.Mpi_sum( jd );
    minD = project->subdom.Mpi_min( minD );
    maxD = project->subdom.Mpi_max( maxD );
#   endif
    //////////////////////////////////////////////////////////////////////////////////////

    // compute useful values for K and D where they are negative -------------------------
    if( jk || jd )
    {
      REPORT::rpt.Message( 3, "%-25s%d %s\n\n", " ", jk, "nodes with K out of range" );
      REPORT::rpt.Message( 3, "%-25s%d %s\n\n", " ", jd, "nodes with D out of range" );
    }

    REPORT::rpt.Message( 3, "%-25sminimum of K: %le\n", " ", minK );
    REPORT::rpt.Message( 3, "%-25smaximum of K: %le\n", " ", maxK );
    REPORT::rpt.Message( 3, "%-25sminimum of D: %le\n", " ", minD );
    REPORT::rpt.Message( 3, "%-25smaximum of D: %le\n", " ", maxD );


    Validate( project, np, node, ne, cent, elem );


    // compute midside values (linear interpolation) -------------------------------------

    if( linearShape )
    {
      for( int e=0; e<ne; e++ )
      {
        ELEM* el = elem[e];

        int ncn = el->Getncn();
        int nnd = el->Getnnd();

        for( int i=ncn; i<nnd; i++ )
        {
          // get left and right corner node to midside node i

          int    il, ir;
          double left, rght;

          el->GetQShape()->getCornerNodes( i, &il, &ir );

          left = el->nd[il]->v.K;
          rght = el->nd[ir]->v.K;
          el->nd[i]->v.K = 0.5 * (left + rght);

          left = el->nd[il]->v.D;
          rght = el->nd[ir]->v.D;
          el->nd[i]->v.D = 0.5 * (left + rght);
        }
      }
    }


    // compute time derivatives ----------------------------------------------------------

    rg->ReportCuPe( dt, project->vk );


    if( !steadyFlow )
    {
      double iTheta = 1.0  -  1.0 / project->timeint.thetaTurb;

      for( int i=0; i<np; i++ )
      {
        if(     isFS(node[i]->flag, NODE::kDry)
            ||  isFS(node[i]->flag, NODE::kMarsh) )
        {
          node[i]->v.dKdt =
          node[i]->v.dDdt = 0.0;
        }
        else
        {
          double K, pK, D, pD, pdKdt, pdDdt;
          VARS *v, *vo;

          v  = &(node[i]->v);
          vo = &(node[i]->vo);

          K     = v->K;
          pK    = vo->K;
          pdKdt = vo->dKdt;

          D     = v->D;
          pD    = vo->D;
          pdDdt = vo->dDdt;

          // compute derivatives at actual time step
          node[i]->v.dKdt = iTheta*pdKdt + thdt*(K - pK);
          node[i]->v.dDdt = iTheta*pdDdt + thdt*(D - pD);
        }
      }
    }


    // -----------------------------------------------------------------------------------

    if( conv  ||  it == project->actualCycit-1 )
    {
      if( REPORT::rpt.level == 1  &&  it == project->actualCycit-1 )
      {
        REPORT::rpt.Message( 1, "\n\n%-25s%s: %d\n\n",
                                " (EQS_KD2D::Execute)", "finished in iteration step", it+1 );

        REPORT::rpt.Message( 1, "\n\n%-25s%s\n\n %s\n\n",
                                " (EQS_KD2D::Execute)", "convergence parameters ...",
                                " variable   node          average        maximum" );

        REPORT::rpt.Message( 1, "      %1c     %5d       %12.5le   %12.5le %s\n",
                                'K', noAbsK+1, aveAbsK, maxAbsK, "     (abs)" );

        REPORT::rpt.Message( 1, "      %1c     %5d       %12.5lf   %12.5lf %s\n\n",
                                ' ', noPerK+1, avePerK, maxPerK, "     ( % )" );

        REPORT::rpt.Message( 1, "      %1c     %5d       %12.5le   %12.5le %s\n",
                                'D', noAbsD+1, aveAbsD, maxAbsD, "     (abs)" );

        REPORT::rpt.Message( 1, "      %1c     %5d       %12.5lf   %12.5lf %s\n\n",
                                ' ', noPerD+1, avePerD, maxPerD, "     ( % )" );
      }

      break;
    }
  }


  // -------------------------------------------------------------------------------------
  // finally:
  // compute eddy viscosity from revised turbulence parameters

  rg->Turbulence( project );


  // -------------------------------------------------------------------------------------

  MEMORY::memo.Detach( B );
  MEMORY::memo.Detach( xKD );

  if( cxK )  MEMORY::memo.Detach( cxK );
  if( cxD )  MEMORY::memo.Detach( cxD );
  if( cent ) MEMORY::memo.Detach( cent );
  if( xKDo ) MEMORY::memo.Detach( xKDo );
  if( cxKo ) MEMORY::memo.Detach( cxKo );
  if( cxDo ) MEMORY::memo.Detach( cxDo );


  // -------------------------------------------------------------------------------------

  if( !conv )        project->errLevel |= kErr_some_errors | kErr_no_conv_nr;
  if( diverged_cg )  project->errLevel |= diverged_cg | kErr_no_conv_cg;
}
コード例 #28
0
void preProcess(const GRID & g, int i, int j, VVV& ava)
{
     if(g[i][j] != '.')
	  return;
     int x, y;
     //down check
     x = i, y = j;
     while(x < g.size() && g[x][y] != '#')
     {
	  Pair p;
	  p.x = x;
	  p.y = y;
	  ava[i][j].push_back(p);	  
	  --x;
     }
     
     //left check
     x = i, y = j;
     while(y < g[0].size() && g[x][y] != '#')
     {
	  Pair p;
	  p.x = x;
	  p.y = y;
	  ava[i][j].push_back(p);	  
	  --y;
     }

     //up left check
     x = i, y = j;
     while(x >= 0 && y >= 0 && x < g.size() && y < g[0].size() && g[x][y] != '#')
     {
	  Pair p;
	  p.x = x;
	  p.y = y;
	  ava[i][j].push_back(p);	  
	  --x, --y;
     }
     
     //up right check
     x = i, y = j;
     while(x >= 0 && y >= 0 && x < g.size() && y < g[0].size() && g[x][y] != '#')
     {
	  Pair p;
	  p.x = x;
	  p.y = y;
	  ava[i][j].push_back(p);
	  --x, ++y;
     }
     
     //down check
     x = i, y = j;
     while(x < g.size() && g[x][y] != '#')
     {
	  Pair p;
	  p.x = x;
	  p.y = y;
	  ava[i][j].push_back(p);	  
	  ++x;
     }
     
     //right check
     x = i, y = j;
     while(y < g[0].size() && g[x][y] != '#')
     {
	  Pair p;
	  p.x = x;
	  p.y = y;
	  ava[i][j].push_back(p);	  
	  ++y;
     }

     //down left check
     x = i, y = j;
     while(x >= 0 && y >= 0 && x < g.size() && y < g[0].size() && g[x][y] != '#')
     {
	  Pair p;
	  p.x = x;
	  p.y = y;
	  ava[i][j].push_back(p);	  
	  ++x, --y;
     }
     
     //down right check
     x = i, y = j;
     while(x >= 0 && y >= 0 && x < g.size() && y < g[0].size() && g[x][y] != '#')
     {
	  Pair p;
	  p.x = x;
	  p.y = y;
	  ava[i][j].push_back(p);
	  ++x, ++y;
     }
}
コード例 #29
0
void ConstructGrid(OstreamGMV3DFmt& Out, 
		   GRID const& G,
		   GEOM const& GEO,
		   heterogeneous_list::List<GF,MOREGFS> GFS)
{
  typedef OstreamGMV3DFmt GMV3D;
  std::ostream& out = Out.Out();
  typedef grid_types<GRID> gt;
  typedef grid_types<GMV3D::archetype_type> gmv_agt;

  out << "gmvinput ascii\n";
  out << "nodev " << G.NumOfVertices() << '\n';

  for(typename gt::VertexIterator v(G); ! v.IsDone(); ++v)
    out << GEO.coord(*v) << '\n';

  // map G's vertices to GMV numbers, starting from 1.
  element_numbering<typename gt::Vertex> G2GMV(G,1);

  // map archetypes of G to those of GMV
  typedef partial_grid_morphism<typename gt::archetype_type,
                                GMV3D::archetype_type>  
    morphism_type;
 
  bijective_mapping<typename gt::archetype_type const*,
                    std::pair<morphism_type, int> > 
    phi;

  for(typename gt::archetype_iterator a = G.BeginArchetype();
      a != G.EndArchetype(); ++a) {
    bool found = false;
    int cnt_a = 0; // could be GMV::archetype_handle
    for(GMV3D::archetype_iterator a_gmv = Out.BeginArchetype();
	a_gmv != Out.EndArchetype(); ++a_gmv, ++cnt_a) {
      morphism_type phi_a(*a,*a_gmv);
      found = construct_isomorphism(*a,*a_gmv, phi_a);
      if(found) {
	phi[&(*a)] = std::make_pair(phi_a,cnt_a);
	break;
      }
    }
    ENSURE(found, "sorry, no mapping to GMV cell type found!\n",1);
    // should use the general cell feature of GMV.
  }

  // map cells
  out << "cells " << G.NumOfCells() << "\n";
  for(typename gt::CellIterator c(G); ! c.IsDone(); ++c) {
    //            phi_a.inv        c.V()        G2GMV   
    // gmv-archetype -> G::archetype -> G::global -> GMV::global
    morphism_type const& phi_a = phi(&G.ArchetypeOf(*c)).first;
    int                  cnt_a = phi(&G.ArchetypeOf(*c)).second;
    GMV3D::archetype_type const& archetype_gmv(phi_a.ImgGrid());
    out << Out.name(cnt_a) << " "
	<< archetype_gmv.NumOfVertices() << " ";
    for(gmv_agt::VertexIterator vc(archetype_gmv); !vc.IsDone(); ++vc)
      out << G2GMV( (*c).V(phi_a.inverse()(*vc)))  << " ";
    out << '\n';
  }

  Out.copy_grid_functions(GFS);
  out << "endgmv\n";
}
コード例 #30
0
ファイル: EqsD2D.cpp プロジェクト: markuszi/Rismo2D
void EQS_D2D::Execute( PROJECT* project, int steadyFlow, int linearShape )
{
  MODEL* model = project->M2D;
  GRID*  rg    = project->M2D->region;

  NODE** node  = model->node;
  ELEM** elem  = model->elem;

  int np       = model->np;
  int ne       = model->ne;

  int div_cg   = 0;

  double* B    = NULL;
  double* X    = NULL;

  model->Incinit();

  // print information on actual iteration -----------------------------------------------
  project->PrintTheCycle( 1 );
  REPORT::rpt.PrintTime( 1 );

  // set parameters according to time integration and relaxation -------------------------
  double th = project->timeint.thetaTurb;
  double dt = project->timeint.incTime.Getsec();

  if( fabs(th) < 1.0e-10  &&  fabs(dt) < 1.0e-10 )
  {
    REPORT::rpt.Error( kParameterFault, "theta and timeInterval too small (EQS_D2D::execute - 1)" );
  }

  double thdt = 1.0 / dt / th;

  double dt_KD;
  double relaxDt_KD = project->timeint.relaxTimeTurb.Getsec();

  int relaxMethod = project->relaxMethod;

  if( steadyFlow )
  {
    if( relaxMethod >= 3 )
    {
      dt_KD = relaxDt_KD;
      relaxThdt_KD = 1.0 / dt_KD;
    }
    else
    {
      dt_KD = dt;
      relaxThdt_KD = 0.0;
    }

    for( int i=0; i<np; i++ )
    {
      node[i]->v.dDdt = 0.0;
    }
  }
  else
  {
    if( relaxMethod >= 3 )
    {
      dt_KD = relaxDt_KD;
    }
    else
    {
      dt_KD = dt;
    }

    relaxThdt_KD = 1.0 / dt_KD / th;

    // time prediction -------------------------------------------------------------------
    for( int i=0; i<np; i++ )
    {
      VARS* v = &node[i]->v;

      //VARS* vo = &(node[i]->vo);

      //v->D    = vo->D  +  vo->dDdt * dt;
      //v->dDdt = (1.0 - 1.0/th)*vo->dDdt + thdt*(v->D - vo->D);

      v->dDdt = 0.0;
    }
  }

  // check KD-values for validity (>= 0) -------------------------------------------------
  Validate( np, node, project );

  // determine friction coefficients -----------------------------------------------------
  model->DoFriction( project );

  // initialize Reynolds stresses and eddy viscosity -------------------------------------
  rg->Turbulence( project );

  // set KD boundary conditions ----------------------------------------------------------
  model->SetBoundKD( project );


  // -------------------------------------------------------------------------------------

  int conv = true;

  for( int it=0; it<project->actualCycit; it++ )
  {
    conv = true;

    // print information on actual iteration ---------------------------------------------
    if( it > 0 )
    {
      project->PrintTheCycle( it+1 );
      REPORT::rpt.PrintTime( 1 );
    }

    // initialize Reynolds stresses and eddy viscosity -----------------------------------
    if( it > 0  &&  isFS(project->actualTurb, BCONSET::kVtIterat)
                && !isFS(project->actualTurb, BCONSET::kVtPrandtlKol) )
    {
      rg->Turbulence( project );
    }

    // set up equation numbers -----------------------------------------------------------
    if( model->Getinit() != modelInit )
    {
      initStructure = true;
      modelInit = model->Getinit();

      project->fix[0] = BCON::kFixD;

      project->elemKind = ELEM::kRegion;

      
      SetEqno( model, 1, 1, 0, project->fix, project->elemKind );

      if( B )  MEMORY::memo.Detach( B );
      if( X )  MEMORY::memo.Detach( X );

      B = (double*) MEMORY::memo.Array_eq( neq );
      X = (double*) MEMORY::memo.Array_eq( neq );
    }

    // solve equations with frontal solving algorithm ------------------------------------
    for( int i=0; i<neq; i++ ) X[i] = 0.0;

    div_cg = Solve( model, neq, B, X, project );


    // -----------------------------------------------------------------------------------
    // statistics

    REPORT::rpt.Message( 1, "\n\n%-25s%s\n\n %s\n\n",
                            " (EQS_D2D::Execute)","convergence parameters ...",
                            " variable   node           average          maximum" );


    // compute averaged changes and standard deviation of D ------------------------------
    double stdevD  = 0.0;
    double aveAbsD = 0.0;

    for( int i=0; i<np; i++ )
    {
      int eqno;
      double dD = 0.0;

      eqno = GetEqno( node[i], 0 );
      if( eqno >= 0 )  dD = X[eqno];

      aveAbsD += dD;
      stdevD  += dD*dD;
    }

    int nptot = 0;

    for( int i=0; i<np; i++ )
    {
      NODE* nd = rg->Getnode(i);
      if( !isFS(nd->flag, NODE::kInface_DN) )  nptot++;
    }

    //////////////////////////////////////////////////////////////////////////////////////
    // MPI: broadcast statistic
#   ifdef _MPI_
    aveAbsD = project->subdom.Mpi_sum( aveAbsD );
    stdevD  = project->subdom.Mpi_sum( stdevD );

    nptot   = project->subdom.Mpi_sum( nptot );
#   endif
    //////////////////////////////////////////////////////////////////////////////////////

    aveAbsD /= nptot;
    stdevD   = sqrt( stdevD / nptot );

    double norm   = stdevD;
    double fractD = 2.0 * sqrt( stdevD );


    // compute maximum changes of K and D limited to ~95% fractile -----------------------

    int    cntD    = 0;

    int    noPerD  = 0;
    double avePerD = 0.0;
    double maxPerD = 0.0;

    int    noAbsD  = 0;
    double maxAbsD = 0.0;

    for( int i=0; i<np; i++ )
    {
      int eqno;
      double dK = 0.0;
      double dD = 0.0;

      eqno = GetEqno( node[i], 0 );
      if( eqno >= 0 )
      {
        dD = X[eqno];
        if( fabs(dD) > project->maxDeltaKD  &&  fabs(dD) > fractD )
        {
          X[eqno] = dD/fabs(dD) * fractD;
        }
      }

      if( node[i]->v.D + dD > 0.0 )
      {
        if( fabs(dD) > fabs(maxAbsD) )
        {
          maxAbsD = dD;
          noAbsD = node[i]->Getname();
        }

        if( node[i]->v.D > 0.0 )
        {
          double per = dD / node[i]->v.D;

          avePerD += fabs(per);
          cntD++;

          if( fabs(per) > fabs(maxPerD) )
          {
            maxPerD = per;
            noPerD = node[i]->Getname();
          }
        }
      }
    }

    //////////////////////////////////////////////////////////////////////////////////////
    // MPI: broadcast statistic
#   ifdef _MPI_
    cntD    = project->subdom.Mpi_sum( cntD );
    maxAbsD = project->subdom.Mpi_max( maxAbsD );
    avePerD = project->subdom.Mpi_sum( avePerD );
    maxPerD = project->subdom.Mpi_max( maxPerD );
#   endif
    //////////////////////////////////////////////////////////////////////////////////////

    avePerD /= cntD;

    REPORT::rpt.Message( 1, "      %1c     %5d       %12.5le   %12.5le %s\n",
                            'D', noAbsD+1, aveAbsD, maxAbsD, "     (abs)" );

    REPORT::rpt.Message( 1, "      %1c     %5d       %12.5lf   %12.5lf %s\n\n",
                            ' ', noPerD+1, avePerD, maxPerD, "     ( % )" );

    if( fabs(maxAbsD) > project->convKD )  conv = false;


    // determine relaxation parameter for NEWTON-RAPHSON ---------------------------------

    double relax;

    double maxKD = fabs(maxAbsD);

    switch( relaxMethod )
    {
      default:
        REPORT::rpt.Warning( kParameterFault,
                             "relaxation method %d not supported", relaxMethod );

      case 0:
        relax = 1.0;

        REPORT::rpt.Message( 1, "\n%-25s%s %12.4le\n %s %12.4le\n\n",
                                " ", "relaxation:   norm  =", norm,
                                " ", "              relax =", relax );
        break;

      case 2:
        relax = project->maxDeltaKD / maxKD;

        if( relax > 1.0 )  relax = 1.0;

        REPORT::rpt.Message( 1, "\n%-25s%s %12.4le\n%-25s%s %12.4le\n\n",
                                " ", "relaxation:   norm  =", norm,
                                " ", "              relax =", relax );
        break;

      case 3:
      case 4:
        REPORT::rpt.Message( 1, "\n%-25s%s %12.4le\n",
                                " ", "relaxed time: dt_KD =", dt_KD );

        if( dt_KD < dt )  conv = false;

        relax = project->maxDeltaKD / maxKD;

        dt_KD *= relax;

        if( dt_KD > dt )          dt_KD = dt;
        if( dt_KD < relaxDt_KD )  dt_KD = relaxDt_KD;

        if( steadyFlow ) relaxThdt_KD = 1.0 / dt_KD;
        else             relaxThdt_KD = 1.0 / dt_KD / th;

        if( relax > 1.0 )  relax = 1.0;

        REPORT::rpt.Message( 1, "\n%-25s%s %12.4le\n%-25s%s %12.4le\n\n",
                                " ", "relaxation:   norm  =", norm,
                                " ", "              relax =", relax );
        break;
    }


    // update ----------------------------------------------------------------------------

    for( int i=0; i<np; i++ )
    {
      int n = GetEqno( node[i], 0 );
      if( n >= 0 )  node[i]->v.D += relax * X[n];
    }


    // check for range of values ---------------------------------------------------------

    double minD = 0.0;
    double maxD = 0.0;

    int first = true;

    int jd = 0;

    for( int i=0; i<np; i++ )
    {
      if( first )
      {
        first = false;
        minD  =
        maxD  = node[i]->v.D;
      }
      else
      {
        if( node[i]->v.D < minD )  minD = node[i]->v.D;
        if( node[i]->v.D > maxD )  maxD = node[i]->v.D;
      }

      if( node[i]->v.D <= 0.0 )
      {
//        node[i]->v.D = project->minD;
        if( GetEqno(node[i],1) >= 0 )  jd++;
      }
    }


    // compute useful values for K and D where they are negative -------------------------
    if( jd )
    {
      REPORT::rpt.Message( 1, "%-25s%d %s\n\n", " ", jd, "nodes with D out of range" );
      Validate( np, node, project );
    }

    REPORT::rpt.Message( 1, "%-25sminimum of D: %le\n", " ", minD );
    REPORT::rpt.Message( 1, "%-25smaximum of D: %le\n", " ", maxD );


    // compute time derivatives ----------------------------------------------------------

    rg->ReportCuPe( dt, project->vk );


    if( !steadyFlow )
    {
      double iTheta;

      iTheta  = 1.0  -  1.0 / project->timeint.thetaTurb;

      for( int i=0; i<np; i++ )
      {
        if(     isFS(node[i]->flag, NODE::kDry)
            ||  isFS(node[i]->flag, NODE::kMarsh) )
        {
          node[i]->v.dDdt = 0.0;
        }

        else
        {
          double D, pD, pdDdt;
          VARS *v, *vo;

          v  = &(node[i]->v);
          vo = &(node[i]->vo);

          D     = v->D;
          pD    = vo->D;
          pdDdt = vo->dDdt;

          // compute derivatives at actual time step
          node[i]->v.dDdt = iTheta*pdDdt + thdt*(D - pD);
        }
      }
    }


    if( conv )  break;
  }


  // finally: compute eddy viscosity from revised turbulence parameters K,D --------------

  rg->Turbulence( project );

  // -------------------------------------------------------------------------------------


  MEMORY::memo.Detach( B );
  MEMORY::memo.Detach( X );


  if( !conv )   project->errLevel |= kErr_some_errors | kErr_no_conv_nr;
  if( div_cg )  project->errLevel |= div_cg | kErr_no_conv_cg;
}