<commit_before>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// GRINS - General Reacting Incompressible Navier-Stokes
//
// Copyright (C) 2010-2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-

// This class
#include "grins/steady_mesh_adaptive_solver.h"

// GRINS
#include "grins/solver_context.h"
#include "grins/multiphysics_sys.h"

// libMesh
#include "libmesh/error_vector.h"
#include "libmesh/steady_solver.h"

namespace GRINS
{

  SteadyMeshAdaptiveSolver::SteadyMeshAdaptiveSolver( const GetPot& input )
    : MeshAdaptiveSolverBase( input )
  {
    return;
  }

  SteadyMeshAdaptiveSolver::~SteadyMeshAdaptiveSolver()
  {
    return;
  }

  void SteadyMeshAdaptiveSolver::init_time_solver( MultiphysicsSystem* system )
  {
    libMesh::SteadySolver* time_solver = new libMesh::SteadySolver( *(system) );

    system->time_solver = libMesh::AutoPtr<libMesh::TimeSolver>( time_solver );

    return;
  }

  void SteadyMeshAdaptiveSolver::solve( SolverContext& context )
  {
    // Mesh and mesh refinement
    libMesh::MeshBase& mesh = context.equation_system->get_mesh();
    this->build_mesh_refinement( mesh );

    // This output cannot be toggled in the input file.
    out << "Performing " << this->_max_r_steps << " adaptive refinements" << std::endl;

    // GRVY timers contained in here (if enabled)
    for ( unsigned int r_step = 0; r_step < this->_max_r_steps; r_step++ )
      {
        // Solve the forward problem
        context.system->solve();

        libMesh::NumericVector<Number>& primal_solution = *(context.system->solution);
        if( context.output_vis )
          {
            context.vis->output( context.equation_system );
          }

        // Solve adjoint system
        context.system->adjoint_solve();

        // At the moment output data is overwritten every mesh refinement step
        if( output_vis && this->_output_adjoint_sol )
          {
            libMesh::NumericVector<Number>& dual_solution = context.system->get_adjoint_solution(0);

            // Swap primal and dual to write out dual solution
            primal_solution.swap( dual_solution );
            vis->output( equation_system );
            primal_solution.swap( dual_solution );
          }

        if( context.output_residual )
          {
            context.vis->output_residual( context.equation_system, context.system );
          }

        // Now we construct the data structures for the mesh refinement process
        libMesh::ErrorVector error;

        context.error_estimator->estimate_error( *context.system, error );

        // Plot error vector
        if( this->_plot_cell_errors )
          {
            error.plot_error( this->_error_plot_prefix+".exo", mesh );
          }

        if( this->_absolute_global_tolerance >= 0. && this->_nelem_target == 0.)
          {
            _mesh_refinement->flag_elements_by_error_tolerance( error );
          }
        // Adaptively refine based on reaching a target number of elements
        else
          {
            if( mesh.n_active_elem() >= this->_nelem_target )
              {
                std::cout<<"We reached the target number of elements."<<std::endl <<std::endl;
                break;
              }

            _mesh_refinement->flag_elements_by_nelem_target( error );
          }
        _mesh_refinement->refine_and_coarsen_elements();

        // Dont forget to reinit the system after each adaptive refinement!
        equation_system->reinit();

        // This output cannot be toggled in the input file.
        std::cout << "Refinement step " << r_step+1 << "/" << this->_max_r_steps
                  << ": refined mesh to " << mesh.n_active_elem() << " elements."
                  << std::endl << std::endl;
      }

    return;
  }

} // end namespace GRINS
<commit_msg>Check if we need to do the adjoint solve before actually doing the adjoint solve.<commit_after>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// GRINS - General Reacting Incompressible Navier-Stokes
//
// Copyright (C) 2010-2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-

// This class
#include "grins/steady_mesh_adaptive_solver.h"

// GRINS
#include "grins/solver_context.h"
#include "grins/multiphysics_sys.h"

// libMesh
#include "libmesh/error_vector.h"
#include "libmesh/steady_solver.h"

namespace GRINS
{

  SteadyMeshAdaptiveSolver::SteadyMeshAdaptiveSolver( const GetPot& input )
    : MeshAdaptiveSolverBase( input )
  {
    return;
  }

  SteadyMeshAdaptiveSolver::~SteadyMeshAdaptiveSolver()
  {
    return;
  }

  void SteadyMeshAdaptiveSolver::init_time_solver( MultiphysicsSystem* system )
  {
    libMesh::SteadySolver* time_solver = new libMesh::SteadySolver( *(system) );

    system->time_solver = libMesh::AutoPtr<libMesh::TimeSolver>( time_solver );

    return;
  }

  void SteadyMeshAdaptiveSolver::solve( SolverContext& context )
  {
    // Mesh and mesh refinement
    libMesh::MeshBase& mesh = context.equation_system->get_mesh();
    this->build_mesh_refinement( mesh );

    // This output cannot be toggled in the input file.
    out << "Performing " << this->_max_r_steps << " adaptive refinements" << std::endl;

    // GRVY timers contained in here (if enabled)
    for ( unsigned int r_step = 0; r_step < this->_max_r_steps; r_step++ )
      {
        // Solve the forward problem
        context.system->solve();

        libMesh::NumericVector<Number>& primal_solution = *(context.system->solution);
        if( context.output_vis )
          {
            context.vis->output( context.equation_system );
          }

        // Solve adjoint system
        if( _do_adjoint_solve )
          {
            context.system->adjoint_solve();
          }

        // At the moment output data is overwritten every mesh refinement step
        if( output_vis && this->_output_adjoint_sol && _do_adjoint_solve )
          {
            libMesh::NumericVector<Number>& dual_solution = context.system->get_adjoint_solution(0);

            // Swap primal and dual to write out dual solution
            primal_solution.swap( dual_solution );
            vis->output( equation_system );
            primal_solution.swap( dual_solution );
          }

        if( context.output_residual )
          {
            context.vis->output_residual( context.equation_system, context.system );
          }

        // Now we construct the data structures for the mesh refinement process
        libMesh::ErrorVector error;

        context.error_estimator->estimate_error( *context.system, error );

        // Plot error vector
        if( this->_plot_cell_errors )
          {
            error.plot_error( this->_error_plot_prefix+".exo", mesh );
          }

        if( this->_absolute_global_tolerance >= 0. && this->_nelem_target == 0.)
          {
            _mesh_refinement->flag_elements_by_error_tolerance( error );
          }
        // Adaptively refine based on reaching a target number of elements
        else
          {
            if( mesh.n_active_elem() >= this->_nelem_target )
              {
                std::cout<<"We reached the target number of elements."<<std::endl <<std::endl;
                break;
              }

            _mesh_refinement->flag_elements_by_nelem_target( error );
          }
        _mesh_refinement->refine_and_coarsen_elements();

        // Dont forget to reinit the system after each adaptive refinement!
        equation_system->reinit();

        // This output cannot be toggled in the input file.
        std::cout << "Refinement step " << r_step+1 << "/" << this->_max_r_steps
                  << ": refined mesh to " << mesh.n_active_elem() << " elements."
                  << std::endl << std::endl;

      } // r_step for-loop

    return;
  }

} // end namespace GRINS
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkXRenderWindow.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1996 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include <math.h>
#include <stdlib.h>
#include <iostream.h>
#include "vtkXRenderWindow.h"
#include "vtkXRenderWindowInteractor.h"

vtkXRenderWindow::vtkXRenderWindow()
{
  this->DisplayId = (Display *)NULL;
  this->WindowId = (Window)NULL;
  this->NextWindowId = (Window)NULL;
  this->ColorMap = (Colormap)NULL;
}

vtkXRenderWindow::~vtkXRenderWindow()
{
  if (this->Interactor) this->Interactor->Delete();
}

// Description:
// Get the size of the screen in pixels
int *vtkXRenderWindow::GetScreenSize()
{
  // get the default display connection
  if (!this->DisplayId)
    {
    this->DisplayId = XOpenDisplay((char *)NULL);
    if (this->DisplayId == NULL)
      {
      vtkErrorMacro(<< "bad X server connection.\n");
      }
    }

  this->ScreenSize[0] =
    DisplayWidth(this->DisplayId, DefaultScreen(this->DisplayId));
  this->ScreenSize[1] =
    DisplayHeight(this->DisplayId, DefaultScreen(this->DisplayId));

  return this->ScreenSize;
}

// Description:
// Get the current size of the window in pixels.
int *vtkXRenderWindow::GetSize(void)
{
  XWindowAttributes attribs;

  // if we aren't mapped then just return the ivar
  if (!this->Mapped)
    {
    return(this->Size);
    }

  //  Find the current window size
  XGetWindowAttributes(this->DisplayId,
		       this->WindowId, &attribs);

  this->Size[0] = attribs.width;
  this->Size[1] = attribs.height;

  return this->Size;
}

// Description:
// Get the position in screen coordinates (pixels) of the window.
int *vtkXRenderWindow::GetPosition(void)
{
  XWindowAttributes attribs;
  int x,y;
  Window child;

  // if we aren't mapped then just return the ivar
  if (!this->Mapped)
    {
    return(this->Position);
    }

  //  Find the current window size
  XGetWindowAttributes(this->DisplayId, this->WindowId, &attribs);
  x = attribs.x;
  y = attribs.y;

  XTranslateCoordinates(this->DisplayId,this->WindowId,
		 RootWindowOfScreen(ScreenOfDisplay(this->DisplayId,0)),
			x,y,&this->Position[0],&this->Position[1],&child);

  return this->Position;
}

// Description:
// Get this RenderWindow's X display id.
Display *vtkXRenderWindow::GetDisplayId()
{
  vtkDebugMacro(<< "Returning DisplayId of " << (void *)this->DisplayId << "\n");

  return this->DisplayId;
}

// Description:
// Get this RenderWindow's X window id.
Window vtkXRenderWindow::GetWindowId()
{
  vtkDebugMacro(<< "Returning WindowId of " << (void *)this->WindowId << "\n");

  return this->WindowId;
}

// Description:
// Set this RenderWindow's X window id to a pre-existing window.
void vtkXRenderWindow::SetWindowId(Window arg)
{
  vtkDebugMacro(<< "Setting WindowId to " << (void *)arg << "\n");

  this->WindowId = arg;
}
void vtkXRenderWindow::SetWindowId(void *arg)
{
  this->SetWindowId((Window)arg);
}

// Description:
// Specify the X window id to use if a WindowRemap is done.
void vtkXRenderWindow::SetNextWindowId(Window arg)
{
  vtkDebugMacro(<< "Setting NextWindowId to " << (void *)arg << "\n");

  this->NextWindowId = arg;
}

// Description:
// Set the X display id for this RenderWindow to use to a pre-existing
// X display id.
void vtkXRenderWindow::SetDisplayId(Display  *arg)
{
  vtkDebugMacro(<< "Setting DisplayId to " << (void *)arg << "\n");

  this->DisplayId = arg;
}
void vtkXRenderWindow::SetDisplayId(void *arg)
{
  this->SetDisplayId((Display *)arg);
}

// Description:
// Create an interactor that will work with this renderer.
// Since all subclasses of this class will be running on
// machines that are running X Windows. The correct vtkRenderWindowInteractor
// is the vtkXRenderWindowInteractor. So this object creates one, then type
// casts it and returns a pointer to it.
vtkRenderWindowInteractor *vtkXRenderWindow::MakeRenderWindowInteractor()
{
  this->Interactor = (vtkRenderWindowInteractor *)new vtkXRenderWindowInteractor;
  this->Interactor->SetRenderWindow((vtkRenderWindow *)this);
  return this->Interactor;
}

void vtkXRenderWindow::PrintSelf(ostream& os, vtkIndent indent)
{
  this->vtkRenderWindow::PrintSelf(os,indent);

  os << indent << "Color Map: " << this->ColorMap << "\n";
  os << indent << "Display Id: " << this->GetDisplayId() << "\n";
  os << indent << "Next Window Id: " << this->NextWindowId << "\n";
  os << indent << "Window Id: " << this->GetWindowId() << "\n";
}

<commit_msg>minor init fix<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkXRenderWindow.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1996 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include <math.h>
#include <stdlib.h>
#include <iostream.h>
#include "vtkXRenderWindow.h"
#include "vtkXRenderWindowInteractor.h"

vtkXRenderWindow::vtkXRenderWindow()
{
  this->DisplayId = (Display *)NULL;
  this->WindowId = (Window)NULL;
  this->NextWindowId = (Window)NULL;
  this->ColorMap = (Colormap)NULL;
  this->ScreenSize[0] = 0;
  this->ScreenSize[1] = 0;
}

vtkXRenderWindow::~vtkXRenderWindow()
{
  if (this->Interactor) this->Interactor->Delete();
}

// Description:
// Get the size of the screen in pixels
int *vtkXRenderWindow::GetScreenSize()
{
  // get the default display connection
  if (!this->DisplayId)
    {
    this->DisplayId = XOpenDisplay((char *)NULL);
    if (this->DisplayId == NULL)
      {
      vtkErrorMacro(<< "bad X server connection.\n");
      }
    }

  this->ScreenSize[0] =
    DisplayWidth(this->DisplayId, DefaultScreen(this->DisplayId));
  this->ScreenSize[1] =
    DisplayHeight(this->DisplayId, DefaultScreen(this->DisplayId));

  return this->ScreenSize;
}

// Description:
// Get the current size of the window in pixels.
int *vtkXRenderWindow::GetSize(void)
{
  XWindowAttributes attribs;

  // if we aren't mapped then just return the ivar
  if (!this->Mapped)
    {
    return(this->Size);
    }

  //  Find the current window size
  XGetWindowAttributes(this->DisplayId,
		       this->WindowId, &attribs);

  this->Size[0] = attribs.width;
  this->Size[1] = attribs.height;

  return this->Size;
}

// Description:
// Get the position in screen coordinates (pixels) of the window.
int *vtkXRenderWindow::GetPosition(void)
{
  XWindowAttributes attribs;
  int x,y;
  Window child;

  // if we aren't mapped then just return the ivar
  if (!this->Mapped)
    {
    return(this->Position);
    }

  //  Find the current window size
  XGetWindowAttributes(this->DisplayId, this->WindowId, &attribs);
  x = attribs.x;
  y = attribs.y;

  XTranslateCoordinates(this->DisplayId,this->WindowId,
		 RootWindowOfScreen(ScreenOfDisplay(this->DisplayId,0)),
			x,y,&this->Position[0],&this->Position[1],&child);

  return this->Position;
}

// Description:
// Get this RenderWindow's X display id.
Display *vtkXRenderWindow::GetDisplayId()
{
  vtkDebugMacro(<< "Returning DisplayId of " << (void *)this->DisplayId << "\n");

  return this->DisplayId;
}

// Description:
// Get this RenderWindow's X window id.
Window vtkXRenderWindow::GetWindowId()
{
  vtkDebugMacro(<< "Returning WindowId of " << (void *)this->WindowId << "\n");

  return this->WindowId;
}

// Description:
// Set this RenderWindow's X window id to a pre-existing window.
void vtkXRenderWindow::SetWindowId(Window arg)
{
  vtkDebugMacro(<< "Setting WindowId to " << (void *)arg << "\n");

  this->WindowId = arg;
}
void vtkXRenderWindow::SetWindowId(void *arg)
{
  this->SetWindowId((Window)arg);
}

// Description:
// Specify the X window id to use if a WindowRemap is done.
void vtkXRenderWindow::SetNextWindowId(Window arg)
{
  vtkDebugMacro(<< "Setting NextWindowId to " << (void *)arg << "\n");

  this->NextWindowId = arg;
}

// Description:
// Set the X display id for this RenderWindow to use to a pre-existing
// X display id.
void vtkXRenderWindow::SetDisplayId(Display  *arg)
{
  vtkDebugMacro(<< "Setting DisplayId to " << (void *)arg << "\n");

  this->DisplayId = arg;
}
void vtkXRenderWindow::SetDisplayId(void *arg)
{
  this->SetDisplayId((Display *)arg);
}

// Description:
// Create an interactor that will work with this renderer.
// Since all subclasses of this class will be running on
// machines that are running X Windows. The correct vtkRenderWindowInteractor
// is the vtkXRenderWindowInteractor. So this object creates one, then type
// casts it and returns a pointer to it.
vtkRenderWindowInteractor *vtkXRenderWindow::MakeRenderWindowInteractor()
{
  this->Interactor = (vtkRenderWindowInteractor *)new vtkXRenderWindowInteractor;
  this->Interactor->SetRenderWindow((vtkRenderWindow *)this);
  return this->Interactor;
}

void vtkXRenderWindow::PrintSelf(ostream& os, vtkIndent indent)
{
  this->vtkRenderWindow::PrintSelf(os,indent);

  os << indent << "Color Map: " << this->ColorMap << "\n";
  os << indent << "Display Id: " << this->GetDisplayId() << "\n";
  os << indent << "Next Window Id: " << this->NextWindowId << "\n";
  os << indent << "Window Id: " << this->GetWindowId() << "\n";
}

<|endoftext|>


<commit_before><commit_msg>Explicitly ask for unsigned values when comparing addresses. Not only is this code hard to understand (and possibly broken) otherwise, some versions of GCC complain about the comparison without the cast.<commit_after><|endoftext|>


<commit_before>// RUN: %clang_cc1 -fsyntax-only -verify -faccess-control %s
struct A {};
struct B : public A {};             // Single public base.
struct C1 : public virtual B {};    // Single virtual base.
struct C2 : public virtual B {};
struct D : public C1, public C2 {}; // Diamond
struct E : private A {};            // Single private base. expected-note 3 {{'private' inheritance specifier here}}
struct F : public C1 {};            // Single path to B with virtual.
struct G1 : public B {};
struct G2 : public B {};
struct H : public G1, public G2 {}; // Ambiguous path to B.

enum Enum { En1, En2 };
enum Onom { On1, On2 };

struct Co1 { operator int(); };
struct Co2 { Co2(int); };
struct Co3 { };
struct Co4 { Co4(Co3); operator Co3(); };

// Explicit implicits
void t_529_2()
{
  int i = 1;
  (void)static_cast<float>(i);
  double d = 1.0;
  (void)static_cast<float>(d);
  (void)static_cast<int>(d);
  (void)static_cast<char>(i);
  (void)static_cast<unsigned long>(i);
  (void)static_cast<int>(En1);
  (void)static_cast<double>(En1);
  (void)static_cast<int&>(i);
  (void)static_cast<const int&>(i);

  int ar[1];
  (void)static_cast<const int*>(ar);
  (void)static_cast<void (*)()>(t_529_2);

  (void)static_cast<void*>(0);
  (void)static_cast<void*>((int*)0);
  (void)static_cast<volatile const void*>((const int*)0);
  (void)static_cast<A*>((B*)0);
  (void)static_cast<A&>(*((B*)0));
  (void)static_cast<const B*>((C1*)0);
  (void)static_cast<B&>(*((C1*)0));
  (void)static_cast<A*>((D*)0);
  (void)static_cast<const A&>(*((D*)0));
  (void)static_cast<int B::*>((int A::*)0);
  (void)static_cast<void (B::*)()>((void (A::*)())0);

  (void)static_cast<int>(Co1());
  (void)static_cast<Co2>(1);
  (void)static_cast<Co3>(static_cast<Co4>(Co3()));

  // Bad code below

  (void)static_cast<void*>((const int*)0); // expected-error {{static_cast from 'int const *' to 'void *' is not allowed}}
  (void)static_cast<A*>((E*)0); // expected-error {{inaccessible base class 'struct A'}}
  (void)static_cast<A*>((H*)0); // expected-error {{ambiguous conversion}}
  (void)static_cast<int>((int*)0); // expected-error {{static_cast from 'int *' to 'int' is not allowed}}
  (void)static_cast<A**>((B**)0); // expected-error {{static_cast from 'struct B **' to 'struct A **' is not allowed}}
  (void)static_cast<char&>(i); // expected-error {{non-const lvalue reference to type 'char' cannot be initialized with a value of type 'int'}}
}

// Anything to void
void t_529_4()
{
  static_cast<void>(1);
  static_cast<void>(t_529_4);
}

// Static downcasts
void t_529_5_8()
{
  (void)static_cast<B*>((A*)0);
  (void)static_cast<B&>(*((A*)0));
  (void)static_cast<const G1*>((A*)0);
  (void)static_cast<const G1&>(*((A*)0));

  // Bad code below

  (void)static_cast<C1*>((A*)0); // expected-error {{cannot cast 'struct A *' to 'struct C1 *' via virtual base 'struct B'}}
  (void)static_cast<C1&>(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct C1 &' via virtual base 'struct B'}}
  (void)static_cast<D*>((A*)0); // expected-error {{cannot cast 'struct A *' to 'struct D *' via virtual base 'struct B'}}
  (void)static_cast<D&>(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct D &' via virtual base 'struct B'}}
  (void)static_cast<B*>((const A*)0); // expected-error {{static_cast from 'struct A const *' to 'struct B *' casts away constness}}
  (void)static_cast<B&>(*((const A*)0)); // expected-error {{static_cast from 'struct A const' to 'struct B &' casts away constness}}
  (void)static_cast<E*>((A*)0); // expected-error {{cannot cast 'struct A' to 'struct E' due to inaccessible}}
  (void)static_cast<E&>(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct E' due to inaccessible}}
  (void)static_cast<H*>((A*)0); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n    struct A -> struct B -> struct G1 -> struct H\n    struct A -> struct B -> struct G2 -> struct H}}
  (void)static_cast<H&>(*((A*)0)); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n    struct A -> struct B -> struct G1 -> struct H\n    struct A -> struct B -> struct G2 -> struct H}}
  (void)static_cast<E*>((B*)0); // expected-error {{static_cast from 'struct B *' to 'struct E *' is not allowed}}
  (void)static_cast<E&>(*((B*)0)); // expected-error {{non-const lvalue reference to type 'struct E' cannot be initialized with a value of type 'struct B'}}

  // TODO: Test inaccessible base in context where it's accessible, i.e.
  // member function and friend.

  // TODO: Test DR427. This requires user-defined conversions, though.
}

// Enum conversions
void t_529_7()
{
  (void)static_cast<Enum>(1);
  (void)static_cast<Enum>(1.0);
  (void)static_cast<Onom>(En1);

  // Bad code below

  (void)static_cast<Enum>((int*)0); // expected-error {{static_cast from 'int *' to 'enum Enum' is not allowed}}
}

// Void pointer to object pointer
void t_529_10()
{
  (void)static_cast<int*>((void*)0);
  (void)static_cast<const A*>((void*)0);

  // Bad code below

  (void)static_cast<int*>((const void*)0); // expected-error {{static_cast from 'void const *' to 'int *' casts away constness}}
  (void)static_cast<void (*)()>((void*)0); // expected-error {{static_cast from 'void *' to 'void (*)()' is not allowed}}
}

// Member pointer upcast.
void t_529_9()
{
  (void)static_cast<int A::*>((int B::*)0);

  // Bad code below
  (void)static_cast<int A::*>((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'struct H'}}
  (void)static_cast<int A::*>((int F::*)0); // expected-error {{conversion from pointer to member of class 'struct F'}}
}

// PR 5261 - static_cast should instantiate template if possible
namespace pr5261 {
  struct base {};
  template<typename E> struct derived : public base {};
  template<typename E> struct outer {
    base *pb;
    ~outer() { (void)static_cast<derived<E>*>(pb); }
  };
  outer<int> EntryList;
}

// Initialization by constructor
struct X0;

struct X1 {
  X1();
  X1(X1&);
  X1(const X0&);

  operator X0() const;
};

struct X0 { };

void test_ctor_init() {
  (void)static_cast<X1>(X1());
}

// Casting away constness
struct X2 {
};

struct X3 : X2 {
};

struct X4 {
  typedef const X3 X3_typedef;

  void f() const {
    (void)static_cast<X3_typedef*>(x2);
  }

  const X2 *x2;
};

// PR5897 - accept static_cast from const void* to const int (*)[1].
void PR5879() { (void)static_cast<const int(*)[1]>((const void*)0); }
<commit_msg>Fix my dyslexia.<commit_after>// RUN: %clang_cc1 -fsyntax-only -verify -faccess-control %s
struct A {};
struct B : public A {};             // Single public base.
struct C1 : public virtual B {};    // Single virtual base.
struct C2 : public virtual B {};
struct D : public C1, public C2 {}; // Diamond
struct E : private A {};            // Single private base. expected-note 3 {{'private' inheritance specifier here}}
struct F : public C1 {};            // Single path to B with virtual.
struct G1 : public B {};
struct G2 : public B {};
struct H : public G1, public G2 {}; // Ambiguous path to B.

enum Enum { En1, En2 };
enum Onom { On1, On2 };

struct Co1 { operator int(); };
struct Co2 { Co2(int); };
struct Co3 { };
struct Co4 { Co4(Co3); operator Co3(); };

// Explicit implicits
void t_529_2()
{
  int i = 1;
  (void)static_cast<float>(i);
  double d = 1.0;
  (void)static_cast<float>(d);
  (void)static_cast<int>(d);
  (void)static_cast<char>(i);
  (void)static_cast<unsigned long>(i);
  (void)static_cast<int>(En1);
  (void)static_cast<double>(En1);
  (void)static_cast<int&>(i);
  (void)static_cast<const int&>(i);

  int ar[1];
  (void)static_cast<const int*>(ar);
  (void)static_cast<void (*)()>(t_529_2);

  (void)static_cast<void*>(0);
  (void)static_cast<void*>((int*)0);
  (void)static_cast<volatile const void*>((const int*)0);
  (void)static_cast<A*>((B*)0);
  (void)static_cast<A&>(*((B*)0));
  (void)static_cast<const B*>((C1*)0);
  (void)static_cast<B&>(*((C1*)0));
  (void)static_cast<A*>((D*)0);
  (void)static_cast<const A&>(*((D*)0));
  (void)static_cast<int B::*>((int A::*)0);
  (void)static_cast<void (B::*)()>((void (A::*)())0);

  (void)static_cast<int>(Co1());
  (void)static_cast<Co2>(1);
  (void)static_cast<Co3>(static_cast<Co4>(Co3()));

  // Bad code below

  (void)static_cast<void*>((const int*)0); // expected-error {{static_cast from 'int const *' to 'void *' is not allowed}}
  (void)static_cast<A*>((E*)0); // expected-error {{inaccessible base class 'struct A'}}
  (void)static_cast<A*>((H*)0); // expected-error {{ambiguous conversion}}
  (void)static_cast<int>((int*)0); // expected-error {{static_cast from 'int *' to 'int' is not allowed}}
  (void)static_cast<A**>((B**)0); // expected-error {{static_cast from 'struct B **' to 'struct A **' is not allowed}}
  (void)static_cast<char&>(i); // expected-error {{non-const lvalue reference to type 'char' cannot be initialized with a value of type 'int'}}
}

// Anything to void
void t_529_4()
{
  static_cast<void>(1);
  static_cast<void>(t_529_4);
}

// Static downcasts
void t_529_5_8()
{
  (void)static_cast<B*>((A*)0);
  (void)static_cast<B&>(*((A*)0));
  (void)static_cast<const G1*>((A*)0);
  (void)static_cast<const G1&>(*((A*)0));

  // Bad code below

  (void)static_cast<C1*>((A*)0); // expected-error {{cannot cast 'struct A *' to 'struct C1 *' via virtual base 'struct B'}}
  (void)static_cast<C1&>(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct C1 &' via virtual base 'struct B'}}
  (void)static_cast<D*>((A*)0); // expected-error {{cannot cast 'struct A *' to 'struct D *' via virtual base 'struct B'}}
  (void)static_cast<D&>(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct D &' via virtual base 'struct B'}}
  (void)static_cast<B*>((const A*)0); // expected-error {{static_cast from 'struct A const *' to 'struct B *' casts away constness}}
  (void)static_cast<B&>(*((const A*)0)); // expected-error {{static_cast from 'struct A const' to 'struct B &' casts away constness}}
  (void)static_cast<E*>((A*)0); // expected-error {{cannot cast 'struct A' to 'struct E' due to inaccessible}}
  (void)static_cast<E&>(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct E' due to inaccessible}}
  (void)static_cast<H*>((A*)0); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n    struct A -> struct B -> struct G1 -> struct H\n    struct A -> struct B -> struct G2 -> struct H}}
  (void)static_cast<H&>(*((A*)0)); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n    struct A -> struct B -> struct G1 -> struct H\n    struct A -> struct B -> struct G2 -> struct H}}
  (void)static_cast<E*>((B*)0); // expected-error {{static_cast from 'struct B *' to 'struct E *' is not allowed}}
  (void)static_cast<E&>(*((B*)0)); // expected-error {{non-const lvalue reference to type 'struct E' cannot be initialized with a value of type 'struct B'}}

  // TODO: Test inaccessible base in context where it's accessible, i.e.
  // member function and friend.

  // TODO: Test DR427. This requires user-defined conversions, though.
}

// Enum conversions
void t_529_7()
{
  (void)static_cast<Enum>(1);
  (void)static_cast<Enum>(1.0);
  (void)static_cast<Onom>(En1);

  // Bad code below

  (void)static_cast<Enum>((int*)0); // expected-error {{static_cast from 'int *' to 'enum Enum' is not allowed}}
}

// Void pointer to object pointer
void t_529_10()
{
  (void)static_cast<int*>((void*)0);
  (void)static_cast<const A*>((void*)0);

  // Bad code below

  (void)static_cast<int*>((const void*)0); // expected-error {{static_cast from 'void const *' to 'int *' casts away constness}}
  (void)static_cast<void (*)()>((void*)0); // expected-error {{static_cast from 'void *' to 'void (*)()' is not allowed}}
}

// Member pointer upcast.
void t_529_9()
{
  (void)static_cast<int A::*>((int B::*)0);

  // Bad code below
  (void)static_cast<int A::*>((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'struct H'}}
  (void)static_cast<int A::*>((int F::*)0); // expected-error {{conversion from pointer to member of class 'struct F'}}
}

// PR 5261 - static_cast should instantiate template if possible
namespace pr5261 {
  struct base {};
  template<typename E> struct derived : public base {};
  template<typename E> struct outer {
    base *pb;
    ~outer() { (void)static_cast<derived<E>*>(pb); }
  };
  outer<int> EntryList;
}

// Initialization by constructor
struct X0;

struct X1 {
  X1();
  X1(X1&);
  X1(const X0&);

  operator X0() const;
};

struct X0 { };

void test_ctor_init() {
  (void)static_cast<X1>(X1());
}

// Casting away constness
struct X2 {
};

struct X3 : X2 {
};

struct X4 {
  typedef const X3 X3_typedef;

  void f() const {
    (void)static_cast<X3_typedef*>(x2);
  }

  const X2 *x2;
};

// PR5897 - accept static_cast from const void* to const int (*)[1].
void PR5897() { (void)static_cast<const int(*)[1]>((const void*)0); }
<|endoftext|>


<commit_before>#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <iostream>
#include "Game.h"
#include "PinnedDownNet.h"

using namespace std;

#pragma comment(lib, "Ws2_32.lib")

#define PINNED_DOWN_SERVER_PORT "27015"
#define DEFAULT_BUFLEN 512

int main()
{
	WSADATA wsaData;

	int result;

	// Initialize Winsock.
	result = WSAStartup(MAKEWORD(2,2), &wsaData);

	if (result != 0)
	{
		printf("WSAStartup failed: %d\n", result);

		int i;
		cin >> i;
		return 1;
	}
	else
	{
		printf("Winsock initialized.\n");
	}

	addrinfo hints;
	addrinfo* addressInfo;

	ZeroMemory(&hints, sizeof (hints));
	hints.ai_family = AF_INET;			// IPv4 address family
	hints.ai_socktype = SOCK_STREAM;	// Stream socket.
	hints.ai_protocol = IPPROTO_TCP;	// TCP protocol.
	hints.ai_flags = AI_PASSIVE;		// Returned socket address structure will be used in a call to the bind function.

	// Resolve the local address and port to be used by the server
	result = getaddrinfo(NULL, PINNED_DOWN_SERVER_PORT, &hints, &addressInfo);
	if (result != 0)
	{
		printf("getaddrinfo failed: %d\n", result);
		WSACleanup();

		int i;
		cin >> i;
		return 1;
	}
	else
	{
		printf("Local address resolved.\n");
	}

	// Create a SOCKET for the server to listen for client connections.
	SOCKET listenSocket = INVALID_SOCKET;
	listenSocket = socket(addressInfo->ai_family, addressInfo->ai_socktype, addressInfo->ai_protocol);

	if (listenSocket == INVALID_SOCKET)
	{
		printf("Error at socket(): %ld\n", WSAGetLastError());
		freeaddrinfo(addressInfo);
		WSACleanup();

		int i;
		cin >> i;
		return 1;
	}

	// Setup the TCP listening socket.
    result = bind( listenSocket, addressInfo->ai_addr, (int)addressInfo->ai_addrlen);

    if (result == SOCKET_ERROR)
	{
        printf("bind failed with error: %d\n", WSAGetLastError());
        freeaddrinfo(addressInfo);
        closesocket(listenSocket);
        WSACleanup();

		int i;
		cin >> i;
		return 1;
    }
	else
	{
		printf("TCP socket created.\n");
		freeaddrinfo(addressInfo);
	}

	// Listen for maximum number of connections.
	result = listen(listenSocket, SOMAXCONN);

	if (result == SOCKET_ERROR)
	{
		printf("Listen failed with error: %ld\n", WSAGetLastError());
		closesocket(listenSocket);
		WSACleanup();

		int i;
		cin >> i;
		return 1;
	}
	else
	{
		printf("Listening for %d connections.\n", SOMAXCONN);
	}

	// Accept a single client socket.
	SOCKET clientSocket = accept(listenSocket, NULL, NULL);

	if (clientSocket == INVALID_SOCKET)
	{
		printf("accept failed: %d\n", WSAGetLastError());
		closesocket(listenSocket);
		WSACleanup();

		int i;
		cin >> i;
		return 1;
	}

	char sendbuf[DEFAULT_BUFLEN];
	char recvbuf[DEFAULT_BUFLEN];
	int sendResult;
	int recvbuflen = DEFAULT_BUFLEN;

	// Send three packets.
	for (int i = 0; i < 3; i++)
	{
		ServerEvent packet = ServerEvent();
		packet.eventType = ServerEventType::LoginSuccess;
		memcpy(&sendbuf, &packet.eventType, sizeof(ServerEventType));

		sendResult = send(clientSocket, sendbuf, sizeof(unsigned int), 0);

		if (sendResult == SOCKET_ERROR)
		{
			printf("send failed: %d\n", WSAGetLastError());
			closesocket(clientSocket);
			WSACleanup();

			int i;
			cin >> i;
			return 1;
		}
	}

	// Create new game.
	PinnedDownCore::Game* game = new PinnedDownCore::Game();

	// Receive until the peer shuts down the connection.
	do
	{
		result = recv(clientSocket, recvbuf, recvbuflen, 0);

		if (result > 0)
		{
			ClientEvent packet = ClientEvent();
			memcpy(&packet.eventType, &recvbuf, sizeof(ClientEventType));

			switch (packet.eventType)
			{
			case ClientEventType::CardSelected:
				printf("Card selected.\n");
			}
		}
		else if (result == 0)
		{
			printf("Connection closing...\n");
		}
		else
		{
			printf("recv failed: %d\n", WSAGetLastError());
			closesocket(clientSocket);
			WSACleanup();

			int i;
			cin >> i;
			return 1;
		}
	}
	while (result > 0);

	// Shutdown the send half of the connection since no more data will be sent.
	result = shutdown(clientSocket, SD_SEND);
	if (result == SOCKET_ERROR)
	{
		printf("shutdown failed: %d\n", WSAGetLastError());
		closesocket(clientSocket);
		WSACleanup();

		int i;
		cin >> i;
		return 1;
	}
	else
	{
		printf("Client socket shut down.");
		closesocket(clientSocket);
		WSACleanup();
	}

	int i;
	cin >> i;
	return 0;
}
<commit_msg>CHANGED: Project - Cleaned up server stub.<commit_after>#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <iostream>
#include "Game.h"
#include "PinnedDownNet.h"

using namespace std;

#pragma comment(lib, "Ws2_32.lib")

#define PINNED_DOWN_SERVER_PORT "27015"
#define DEFAULT_BUFLEN 512

void pause()
{
	int i;
	cin >> i;
}

int main()
{
	// Initialize Winsock.
	WSADATA wsaData;
	int result;

	result = WSAStartup(MAKEWORD(2,2), &wsaData);

	if (result != 0)
	{
		printf("Failed to initialize Winsock: %d\n", result);

		pause();
		return 1;
	}
	else
	{
		printf("Winsock initialized.\n");
	}

	// Resolve the local address and port to be used by the server
	addrinfo hints;
	addrinfo* addressInfo;

	ZeroMemory(&hints, sizeof (hints));
	hints.ai_family = AF_INET;			// IPv4 address family
	hints.ai_socktype = SOCK_STREAM;	// Stream socket.
	hints.ai_protocol = IPPROTO_TCP;	// TCP protocol.
	hints.ai_flags = AI_PASSIVE;		// Returned socket address structure will be used in a call to the bind function.

	result = getaddrinfo(NULL, PINNED_DOWN_SERVER_PORT, &hints, &addressInfo);
	if (result != 0)
	{
		printf("Failed to resolve local address and port: %d\n", result);
		WSACleanup();

		pause();
		return 1;
	}
	else
	{
		printf("Local address and port resolved.\n");
	}

	// Create a SOCKET for the server to listen for client connections.
	SOCKET listenSocket = INVALID_SOCKET;
	listenSocket = socket(addressInfo->ai_family, addressInfo->ai_socktype, addressInfo->ai_protocol);

	if (listenSocket == INVALID_SOCKET)
	{
		printf("Failed to create socket: %ld\n", WSAGetLastError());
		freeaddrinfo(addressInfo);
		WSACleanup();

		pause();
		return 1;
	}
	else
	{
		printf("Socket created.\n");
	}

	// Setup the TCP listening socket.
    result = bind( listenSocket, addressInfo->ai_addr, (int)addressInfo->ai_addrlen);

    if (result == SOCKET_ERROR)
	{
        printf("Failed to bind TCP listening socket: %d\n", WSAGetLastError());
        freeaddrinfo(addressInfo);
        closesocket(listenSocket);
        WSACleanup();

		pause();
		return 1;
    }
	else
	{
		printf("TCP socket bound.\n");
		freeaddrinfo(addressInfo);
	}

	// Listen for maximum number of connections.
	result = listen(listenSocket, SOMAXCONN);

	if (result == SOCKET_ERROR)
	{
		printf("Failed to listen for incoming connections: %ld\n", WSAGetLastError());
		closesocket(listenSocket);
		WSACleanup();

		pause();
		return 1;
	}
	else
	{
		printf("Listening for %d connections.\n", SOMAXCONN);
	}

	// Accept a single client socket.
	SOCKET clientSocket = accept(listenSocket, NULL, NULL);

	if (clientSocket == INVALID_SOCKET)
	{
		printf("Failed to accept client socket: %d\n", WSAGetLastError());
		closesocket(listenSocket);
		WSACleanup();

		pause();
		return 1;
	}
	else
	{
		printf("Client connected.\n");
	}

	// Send login ACK.
	char sendbuf[DEFAULT_BUFLEN];
	char recvbuf[DEFAULT_BUFLEN];

	ServerEvent packet = ServerEvent(ServerEventType::LoginSuccess);
	memcpy(&sendbuf, &packet.eventType, sizeof(ServerEventType));

	result = send(clientSocket, sendbuf, sizeof(ServerEventType), 0);

	if (result == SOCKET_ERROR)
	{
		printf("Failed to send packet: %d\n", WSAGetLastError());
		closesocket(clientSocket);
		WSACleanup();

		pause();
		return 1;
	}
	else
	{
		printf("Packet sent.\n");
	}

	// Create new game.
	PinnedDownCore::Game* game = new PinnedDownCore::Game();

	// Receive until the peer shuts down the connection.
	do
	{
		result = recv(clientSocket, recvbuf, DEFAULT_BUFLEN, 0);

		if (result > 0)
		{
			// Process client action.
			ClientAction action = ClientAction();
			memcpy(&action.actionType, &recvbuf, sizeof(ClientActionType));

			switch (action.actionType)
			{
			case ClientActionType::SelectCard:
				printf("Select card.\n");
			}
		}
		else if (result == 0)
		{
			printf("Connection closing...\n");
		}
		else
		{
			printf("Failed to receive packet: %d\n", WSAGetLastError());
			closesocket(clientSocket);
			WSACleanup();

			pause();
			return 1;
		}
	}
	while (result > 0);

	// Shutdown the send half of the connection since no more data will be sent.
	result = shutdown(clientSocket, SD_SEND);

	if (result == SOCKET_ERROR)
	{
		printf("Failed to shut down socket: %d\n", WSAGetLastError());
		closesocket(clientSocket);
		WSACleanup();

		pause();
		return 1;
	}
	else
	{
		printf("Client socket shut down.");
		closesocket(clientSocket);
		WSACleanup();
	}

	pause();
	return 0;
}
<|endoftext|>


<commit_before>/*
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "istream_head.hxx"
#include "ForwardIstream.hxx"

#include <algorithm>

#include <assert.h>
#include <string.h>

class HeadIstream final : public ForwardIstream {
    off_t rest;
    const bool authoritative;

public:
    HeadIstream(struct pool &p, Istream &_input,
                size_t size, bool _authoritative)
        :ForwardIstream(p, _input),
         rest(size), authoritative(_authoritative) {}

    /* virtual methods from class Istream */

    off_t _GetAvailable(bool partial) override;
    off_t _Skip(off_t length) override;
    void _Read() override;

    int _AsFd() override {
        return -1;
    }

    /* virtual methods from class IstreamHandler */
    size_t OnData(const void *data, size_t length) override;
    ssize_t OnDirect(FdType type, int fd, size_t max_length) override;
};

/*
 * istream handler
 *
 */

size_t
HeadIstream::OnData(const void *data, size_t length)
{
    if (rest == 0) {
        input.Close();
        DestroyEof();
        return 0;
    }

    if ((off_t)length > rest)
        length = rest;

    size_t nbytes = InvokeData(data, length);
    assert((off_t)nbytes <= rest);

    if (nbytes > 0) {
        rest -= nbytes;
        if (rest == 0) {
            input.Close();
            DestroyEof();
            return 0;
        }
    }

    return nbytes;
}

ssize_t
HeadIstream::OnDirect(FdType type, int fd, size_t max_length)
{
    if (rest == 0) {
        input.Close();
        DestroyEof();
        return ISTREAM_RESULT_CLOSED;
    }

    if ((off_t)max_length > rest)
        max_length = rest;

    ssize_t nbytes = InvokeDirect(type, fd, max_length);
    assert(nbytes < 0 || (off_t)nbytes <= rest);

    if (nbytes > 0) {
        rest -= (size_t)nbytes;
        if (rest == 0) {
            input.Close();
            DestroyEof();
            return ISTREAM_RESULT_CLOSED;
        }
    }

    return nbytes;
}

/*
 * istream implementation
 *
 */

off_t
HeadIstream::_GetAvailable(bool partial)
{
    if (authoritative) {
        assert(partial ||
               input.GetAvailable(partial) < 0 ||
               input.GetAvailable(partial) >= (off_t)rest);
        return rest;
    }

    off_t available = input.GetAvailable(partial);
    return std::min(available, rest);
}

off_t
HeadIstream::_Skip(off_t length)
{
    if (length >= rest)
        length = rest;

    off_t nbytes = input.Skip(length);
    assert(nbytes <= length);

    if (nbytes > 0)
        rest -= nbytes;

    return nbytes;
}

void
HeadIstream::_Read()
{
    if (rest == 0) {
        input.Close();
        DestroyEof();
    } else {
        ForwardIstream::_Read();
    }
}

/*
 * constructor
 *
 */

Istream *
istream_head_new(struct pool *pool, Istream &input,
                 size_t size, bool authoritative)
{
    return NewIstream<HeadIstream>(*pool, input, size, authoritative);
}
<commit_msg>istream/head: invoke base class in _Skip()<commit_after>/*
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "istream_head.hxx"
#include "ForwardIstream.hxx"

#include <algorithm>

#include <assert.h>
#include <string.h>

class HeadIstream final : public ForwardIstream {
    off_t rest;
    const bool authoritative;

public:
    HeadIstream(struct pool &p, Istream &_input,
                size_t size, bool _authoritative)
        :ForwardIstream(p, _input),
         rest(size), authoritative(_authoritative) {}

    /* virtual methods from class Istream */

    off_t _GetAvailable(bool partial) override;
    off_t _Skip(off_t length) override;
    void _Read() override;

    int _AsFd() override {
        return -1;
    }

    /* virtual methods from class IstreamHandler */
    size_t OnData(const void *data, size_t length) override;
    ssize_t OnDirect(FdType type, int fd, size_t max_length) override;
};

/*
 * istream handler
 *
 */

size_t
HeadIstream::OnData(const void *data, size_t length)
{
    if (rest == 0) {
        input.Close();
        DestroyEof();
        return 0;
    }

    if ((off_t)length > rest)
        length = rest;

    size_t nbytes = InvokeData(data, length);
    assert((off_t)nbytes <= rest);

    if (nbytes > 0) {
        rest -= nbytes;
        if (rest == 0) {
            input.Close();
            DestroyEof();
            return 0;
        }
    }

    return nbytes;
}

ssize_t
HeadIstream::OnDirect(FdType type, int fd, size_t max_length)
{
    if (rest == 0) {
        input.Close();
        DestroyEof();
        return ISTREAM_RESULT_CLOSED;
    }

    if ((off_t)max_length > rest)
        max_length = rest;

    ssize_t nbytes = InvokeDirect(type, fd, max_length);
    assert(nbytes < 0 || (off_t)nbytes <= rest);

    if (nbytes > 0) {
        rest -= (size_t)nbytes;
        if (rest == 0) {
            input.Close();
            DestroyEof();
            return ISTREAM_RESULT_CLOSED;
        }
    }

    return nbytes;
}

/*
 * istream implementation
 *
 */

off_t
HeadIstream::_GetAvailable(bool partial)
{
    if (authoritative) {
        assert(partial ||
               input.GetAvailable(partial) < 0 ||
               input.GetAvailable(partial) >= (off_t)rest);
        return rest;
    }

    off_t available = input.GetAvailable(partial);
    return std::min(available, rest);
}

off_t
HeadIstream::_Skip(off_t length)
{
    if (length >= rest)
        length = rest;

    off_t nbytes = ForwardIstream::Skip(length);
    assert(nbytes <= length);

    if (nbytes > 0)
        rest -= nbytes;

    return nbytes;
}

void
HeadIstream::_Read()
{
    if (rest == 0) {
        input.Close();
        DestroyEof();
    } else {
        ForwardIstream::_Read();
    }
}

/*
 * constructor
 *
 */

Istream *
istream_head_new(struct pool *pool, Istream &input,
                 size_t size, bool authoritative)
{
    return NewIstream<HeadIstream>(*pool, input, size, authoritative);
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

// mapnik
#include <mapnik/json/extract_bounding_box_grammar.hpp>

// boost
#include <boost/spirit/include/qi_omit.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/repository/include/qi_iter_pos.hpp>
// stl
#include <iostream>
#include <string>

namespace mapnik { namespace json {

namespace repo = boost::spirit::repository;

template <typename Iterator, typename ErrorHandler>
extract_bounding_box_grammar<Iterator, ErrorHandler>::extract_bounding_box_grammar()
    : extract_bounding_box_grammar::base_type(start,"bounding boxes")
{
    qi::lit_type lit;
    qi::double_type double_;
    qi::_val_type _val;
    qi::_1_type _1;
    qi::_2_type _2;
    qi::_3_type _3;
    qi::_4_type _4;
    qi::omit_type omit;
    qi::_r1_type _r1;
    qi::_r2_type _r2;
    qi::_a_type _a;
    qi::_b_type _b;
    qi::eps_type eps;
    qi::raw_type raw;
    ascii::char_type char_;
    boost::spirit::repository::qi::iter_pos_type iter_pos;
    using qi::fail;
    using qi::on_error;

    start = features(_r1)
        ;
    features = iter_pos[_a = _1] >> -(lit('{') >> -lit("\"type\"")
                                      >> lit(':') >> lit("\"FeatureCollection\"")
                                      >> *(lit(',') >> (json.key_value - lit("\"features\"")))
                                      >> lit(',') >> lit("\"features\"")
                                      >> lit(':'))
                                 >> lit('[') >> (feature(_r1,_a) % lit(',')) >> lit(']')
        ;
    feature = raw[lit('{')[_a = 1] >> lit("\"type\"") >> lit(':') >> lit("\"Feature\"")
                   >> *(eps(_a > 0) >> (lit('{')[_a += 1]
                                        |
                                        lit('}')[_a -=1]
                                        |
                                        coords[_b = _1]
                                        |
                                        char_))][push_box(_r1, _r2, _b, _1)]
        ;
    coords = lit("\"coordinates\"") >> lit(':') >> (rings_array(_a) | rings (_a) | ring(_a) | pos[calculate_bounding_box(_a,_1)])[_val = _a]
        ;
    pos = lit('[') > -(double_ > lit(',') > double_) > omit[*(lit(',') > double_)] > lit(']')
        ;
    ring = lit('[') >> pos[calculate_bounding_box(_r1,_1)] % lit(',') > lit(']')
        ;
    rings = lit('[') >> ring(_r1)  % lit(',') > lit(']')
        ;
    rings_array = lit('[') >> rings(_r1) % lit(',') > lit(']')
        ;

    // generic json types
    json.value = json.object | json.array | json.string_ | json.number
        ;
    json.pairs = json.key_value % lit(',')
        ;
    json.key_value = (json.string_ >> lit(':') >> json.value)
        ;
    json.object = lit('{') >> *json.pairs >> lit('}')
        ;
    json.array = lit('[')
        >> json.value >> *(lit(',') >> json.value)
        >> lit(']')
        ;
    json.number = json.strict_double
        | json.int__
        | lit("true")
        | lit("false")
        | lit("null")
        ;
    coords.name("Coordinates");
    pos.name("Position");
    ring.name("Ring");
    rings.name("Rings");
    rings_array.name("Rings array");

    // error handler
    on_error<fail>(coords, error_handler(_1, _2, _3, _4));
}

}}
<commit_msg>fix bbox extractor<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

// mapnik
#include <mapnik/json/extract_bounding_box_grammar.hpp>

// boost
#include <boost/spirit/include/qi_omit.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/repository/include/qi_iter_pos.hpp>
// stl
#include <iostream>
#include <string>

namespace mapnik { namespace json {

namespace repo = boost::spirit::repository;

template <typename Iterator, typename ErrorHandler>
extract_bounding_box_grammar<Iterator, ErrorHandler>::extract_bounding_box_grammar()
    : extract_bounding_box_grammar::base_type(start,"bounding boxes")
{
    qi::lit_type lit;
    qi::double_type double_;
    qi::_val_type _val;
    qi::_1_type _1;
    qi::_2_type _2;
    qi::_3_type _3;
    qi::_4_type _4;
    qi::omit_type omit;
    qi::_r1_type _r1;
    qi::_r2_type _r2;
    qi::_a_type _a;
    qi::_b_type _b;
    qi::eps_type eps;
    qi::raw_type raw;
    boost::spirit::standard_wide::char_type char_;
    boost::spirit::repository::qi::iter_pos_type iter_pos;
    using qi::fail;
    using qi::on_error;

    start = features(_r1)
        ;
    features = iter_pos[_a = _1] >> -(lit('{') >> -lit("\"type\"")
                                      >> lit(':') >> lit("\"FeatureCollection\"")
                                      >> *(lit(',') >> (json.key_value - lit("\"features\"")))
                                      >> lit(',') >> lit("\"features\"")
                                      >> lit(':'))
                                 >> lit('[') >> (feature(_r1,_a) % lit(',')) >> lit(']')
        ;
    feature = raw[lit('{')[_a = 1] >> lit("\"type\"") >> lit(':') >> lit("\"Feature\"")
                   >> *(eps(_a > 0) >> (lit('{')[_a += 1]
                                        |
                                        lit('}')[_a -=1]
                                        |
                                        coords[_b = _1]
                                        |
                                        char_))][push_box(_r1, _r2, _b, _1)]
        ;
    coords = lit("\"coordinates\"") >> lit(':') >> (rings_array(_a) | rings (_a) | ring(_a) | pos[calculate_bounding_box(_a,_1)])[_val = _a]
        ;
    pos = lit('[') > -(double_ > lit(',') > double_) > omit[*(lit(',') > double_)] > lit(']')
        ;
    ring = lit('[') >> pos[calculate_bounding_box(_r1,_1)] % lit(',') > lit(']')
        ;
    rings = lit('[') >> ring(_r1)  % lit(',') > lit(']')
        ;
    rings_array = lit('[') >> rings(_r1) % lit(',') > lit(']')
        ;

    // generic json types
    json.value = json.object | json.array | json.string_ | json.number
        ;
    json.pairs = json.key_value % lit(',')
        ;
    json.key_value = (json.string_ >> lit(':') >> json.value)
        ;
    json.object = lit('{') >> *json.pairs >> lit('}')
        ;
    json.array = lit('[')
        >> json.value >> *(lit(',') >> json.value)
        >> lit(']')
        ;
    json.number = json.strict_double
        | json.int__
        | lit("true")
        | lit("false")
        | lit("null")
        ;
    coords.name("Coordinates");
    pos.name("Position");
    ring.name("Ring");
    rings.name("Rings");
    rings_array.name("Rings array");

    // error handler
    on_error<fail>(coords, error_handler(_1, _2, _3, _4));
}

}}
<|endoftext|>


<commit_before>// -*- C++ -*-

// The MIT License (MIT)
//
// Copyright (c) 2017 Alexander Samoilov
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include <iostream>
#include <fstream>
#include <string>
#include <chrono>
#include <boost/program_options.hpp>

struct program_options
{
    bool verbose                     = {false};
    int  flow_type                   = {0};            // legacy Fortran constants for flow type, 50 for sphere, 51 for torus
    std::string input_data           = {""};           // name of the input file e.g. `sphere.dat`, `torus_trgl.dat`
    std::string asy_name             = {""};           // dump streamlines to vector `.asy` file if name is given
};

std::ostream& operator<<(std::ostream& os, program_options const& popt)
{
    os << "program options: " << std::boolalpha << " verbose: " << popt.verbose << std::endl
       << " flow_type: " << popt.flow_type << " input_data: " << popt.input_data << " asy_name: " << popt.asy_name << std::endl;

    return os;
}

program_options parse_command_line(int argc, char** argv)
{
    namespace po = boost::program_options;
    po::options_description desc("allowed options");
    desc.add_options()
            ("help",                   "describe arguments")
            ("verbose",                "be verbose")
            ("flow_type",              po::value<int>(), "legacy Fortran constants for flow type, 50 for sphere, 51 for torus")
            ("input_data",             po::value<std::string>(), "name of the input file e.g. `sphere.dat`, `torus_trgl.dat`")
            ("asy_name",               po::value<std::string>(), "dump streamlines to vector `.asy` file if name is given");
    try
    {
        po::variables_map vm;
        po::store(po::parse_command_line(argc, argv, desc), vm);
        po::notify(vm);
        program_options popt;

        if (vm.count("help")) {
            std::cout << desc << std::endl;
            std::exit(1);
        }

        popt.verbose               = vm.count("verbose");
        if (vm.count("flow_type"))
        {
            popt.flow_type = vm["flow_type"].as<int>();
        }
        if (vm.count("input_data"))
        {
            popt.input_data = vm["input_data"].as<std::string>();
        }
        if (vm.count("asy_name"))
        {
            popt.asy_name = vm["asy_name"].as<std::string>();
        }

        return popt;
    }
    catch(const std::exception& e)
    {
        std::cerr << e.what() << std::endl;
        std::cout << desc << std::endl;
        std::exit(-1);
    }
}

int main(int argc, char **argv)
{
    auto popt = parse_command_line(argc, argv);
    if (popt.verbose) {
        std::cout << popt;
    }

}

<commit_msg>cosmetic.<commit_after>// -*- C++ -*-

// The MIT License (MIT)
//
// Copyright (c) 2017 Alexander Samoilov
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include <iostream>
#include <fstream>
#include <string>
#include <chrono>
#include <boost/program_options.hpp>

struct program_options
{
    bool verbose                     = {false};
    int  flow_type                   = {0};            // legacy Fortran constants for flow type, 50 for sphere, 51 for torus
    std::string input_data           = {""};           // name of the input file e.g. `sphere.dat`, `torus_trgl.dat`
    std::string asy_name             = {""};           // dump streamlines to vector `.asy` file if name is given
};

std::ostream& operator<<(std::ostream& os, program_options const& popt)
{
    os << "program options: " << std::boolalpha << " verbose: " << popt.verbose << std::endl
       << " flow_type: " << popt.flow_type << " input_data: " << popt.input_data << " asy_name: " << popt.asy_name << std::endl;

    return os;
}

program_options parse_command_line(int argc, char** argv)
{
    namespace po = boost::program_options;
    po::options_description desc("allowed options");
    desc.add_options()
            ("help",                   "describe arguments")
            ("verbose",                "be verbose")
            ("flow_type",              po::value<int>(), "legacy Fortran constants for flow type, 50 for sphere, 51 for torus")
            ("input_data",             po::value<std::string>(), "name of the input file e.g. `sphere.dat`, `torus_trgl.dat`")
            ("asy_name",               po::value<std::string>(), "dump streamlines to vector `.asy` file if name is given");
    try
    {
        po::variables_map vm;
        po::store(po::parse_command_line(argc, argv, desc), vm);
        po::notify(vm);
        program_options popt;

        if (vm.count("help")) {
            std::cout << desc << std::endl;
            std::exit(1);
        }

        popt.verbose               = vm.count("verbose");
        if (vm.count("flow_type")) {
            popt.flow_type = vm["flow_type"].as<int>();
        }
        if (vm.count("input_data")) {
            popt.input_data = vm["input_data"].as<std::string>();
        }
        if (vm.count("asy_name")) {
            popt.asy_name = vm["asy_name"].as<std::string>();
        }

        return popt;
    }
    catch(const std::exception& e)
    {
        std::cerr << e.what() << std::endl;
        std::cout << desc << std::endl;
        std::exit(-1);
    }
}

int main(int argc, char **argv)
{
    auto popt = parse_command_line(argc, argv);
    if (popt.verbose) {
        std::cout << popt;
    }

}

<|endoftext|>


<commit_before>/*
 * BackwardChainer.cc
 *
 * Copyright (C) 2014-2016 OpenCog Foundation
 *
 * Authors: Misgana Bayetta <misgana.bayetta@gmail.com>  October 2014
 *          William Ma <https://github.com/williampma>
 *          Nil Geisweiller 2016
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <opencog/util/random.h>

#include <opencog/atomutils/FindUtils.h>
#include <opencog/atomutils/Substitutor.h>
#include <opencog/atomutils/Unify.h>
#include <opencog/atomutils/TypeUtils.h>
#include <opencog/atoms/pattern/PatternLink.h>
#include <opencog/atoms/pattern/BindLink.h>

#include <opencog/query/BindLinkAPI.h>

#include "BackwardChainer.h"
#include "BackwardChainerPMCB.h"
#include "UnifyPMCB.h"
#include "BCLogger.h"

using namespace opencog;

BackwardChainer::BackwardChainer(AtomSpace& as, const Handle& rbs,
                                 const Handle& htarget,
                                 const Handle& vardecl,
                                 const Handle& hfocus_set, // TODO:
                                                           // support
                                                           // focus_set
                                 const BITFitness& fitness)
	: _as(as), _configReader(as, rbs),
	  _init_target(htarget), _init_vardecl(vardecl), _init_fitness(fitness),
	  _bit_as(&as), _iteration(0), _rules(_configReader.get_rules()) {}

UREConfigReader& BackwardChainer::get_config()
{
	return _configReader;
}

const UREConfigReader& BackwardChainer::get_config() const
{
	return _configReader;
}

void BackwardChainer::do_chain()
{
	while (not termination())
	{
		do_step();
	}
}

void BackwardChainer::do_step()
{
	bc_logger().debug("Iteration %d", _iteration);
	_iteration++;

	expand_bit();
	fulfill_bit();
	reduce_bit();
}

bool BackwardChainer::termination()
{
	return _configReader.get_maximum_iterations() <= _iteration;
}

Handle BackwardChainer::get_results() const
{
	HandleSeq results(_results.begin(), _results.end());
	return _as.add_link(SET_LINK, results);
}

void BackwardChainer::expand_bit()
{
	if (_handle2bitnode.empty()) {
		// Initialize the and-BIT of the initial target
		insert_h2b(_init_target, _init_vardecl, _init_fitness);
		init_andbits();

		LAZY_BC_LOG_DEBUG << "Initialize BIT with:" << std::endl
		                  << _handle2bitnode[_init_target].to_string();
	} else {
		// Select an and-BIT and expand it
		const AndBITFCMap::value_type& andbit = select_andbit();
		LAZY_BC_LOG_DEBUG << "Selected and-BIT for expansion:" << std::endl
		                  << andbit.second;
		expand_bit(andbit);
	}
}

void BackwardChainer::expand_bit(const AndBITFCMap::value_type& andbit)
{
	// Select leaf
	BITNode& bitleaf = select_bitleaf(andbit);
	LAZY_BC_LOG_DEBUG << "Selected BIT-node for expansion:" << std::endl
	                  << bitleaf.to_string();

	// Select a valid rule
	Rule rule = select_rule(bitleaf);
	if (not rule.is_valid()) {
		bc_logger().warn("No valid rule for the selected BIT-node, abort expansion");
		return;
	}
	LAZY_BC_LOG_DEBUG << "Selected rule for BIT expansion:" << std::endl
	                  << rule.to_string();

	// Expand the back-inference tree from this target
	expand_bit(andbit, bitleaf, rule);
}

void BackwardChainer::expand_bit(const AndBITFCMap::value_type& andbit,
                                 BITNode& bitleaf, const Rule& rule)
{
	// Make sure that the rule is not a or-child of leaf.
	if (is_in(rule, bitleaf)) {
		bc_logger().debug() << "An equivalent rule has already expanded that BIT-node, abort expansion";
		return;
	}

	// Expand the leaf
	// 1. Append the rule to it
	// 2. Instantiate the premises as BITNodes
	HandleSeq premises(rule.get_premises());
	bitleaf.rules.push_back(rule);
	for (const Handle& premise : premises)
		insert_h2b(premise, rule.get_forward_vardecl(), BITFitness());

	// Expand the associated atomese forward chaining strategy
	Handle fcs = expand_fcs(andbit.second, bitleaf.body, rule);

	// Define new and-BIT and associate new forward chaining strategy
	// to it
	AndBITFCMap::key_type new_leaves(andbit.first);
	new_leaves.erase(bitleaf.body);
	for (const Handle& premise : premises)
		// Make sure that the premise is in _bit_as
		new_leaves.insert(_bit_as.add_atom(premise));
	_andbits[new_leaves] = fcs;
}

Handle BackwardChainer::expand_fcs(const Handle& fcs, const Handle& leaf,
                                   const Rule& rule)
{
	BindLinkPtr fcs_bl(BindLinkCast(fcs));
	Handle fcs_vardecl = fcs_bl->get_vardecl();
	Handle fcs_pattern = fcs_bl->get_body();
	Handle fcs_rewrite = fcs_bl->get_implicand();
	Handle rule_vardecl = rule.get_forward_vardecl();
	HandleSeq premises = rule.get_premises();
	Handle rule_rewrite = rule.get_forward_implicand();

	// Generate new pattern term
	Handle npattern = expand_fcs_pattern(fcs_pattern, leaf, premises);

	// Generate new rewrite term
	Handle nrewrite = expand_fcs_rewrite(fcs_rewrite, leaf, rule_rewrite);

	// Generate new vardecl
	Handle nvardecl = filter_vardecl(merge_vardecl(fcs_vardecl,
	                                               // Mkae sure it is in _bit_as
	                                               _bit_as.add_atom(rule_vardecl)),
	                                 {npattern, nrewrite});

	// Generate new atomese forward chaining strategy
	HandleSeq noutgoings({npattern, nrewrite});
	if (nvardecl.is_defined())
		noutgoings.insert(noutgoings.begin(), nvardecl);
	Handle nfcs = _bit_as.add_link(BIND_LINK, noutgoings);

	LAZY_BC_LOG_DEBUG << "Expand forward chainer strategy:" << std::endl << fcs
	                  << "to:" << std::endl << nfcs;

	return nfcs;
}

Handle BackwardChainer::expand_fcs_pattern(const Handle& fcs_pattern,
                                           const Handle& leaf,
                                           const HandleSeq& premises)
{
	if (fcs_pattern == leaf)
		return _bit_as.add_link(AND_LINK, premises);

	OC_ASSERT(fcs_pattern->getType() == AND_LINK);
	HandleSeq outgoings = fcs_pattern->getOutgoingSet();
	auto it = std::find(outgoings.begin(), outgoings.end(), leaf);
	OC_ASSERT(it != outgoings.end());
	outgoings.erase(it);
	outgoings.insert(outgoings.end(), premises.begin(), premises.end());
	return _bit_as.add_link(AND_LINK, outgoings);
}

Handle BackwardChainer::expand_fcs_rewrite(const Handle& fcs_rewrite,
                                           const Handle& leaf,
                                           const Handle& rule_rewrite)
{
	// Base cases

	// Replace the fcs rewrite atoms by the rule_rewrite if leaf
	if (fcs_rewrite == leaf)
		// rule_rewrite might possibly not be in _bit_as yet, add it
		return _bit_as.add_atom(rule_rewrite);
	// If node and isn't leaf leave alone
	if (fcs_rewrite->isNode())
		return fcs_rewrite;

	// Recursive case

	Type t = fcs_rewrite->getType();
	HandleSeq outgoings;
	for (const Handle& h : fcs_rewrite->getOutgoingSet())
		outgoings.push_back(expand_fcs_rewrite(h, leaf, rule_rewrite));
	return _bit_as.add_link(t, outgoings);
}

void BackwardChainer::fulfill_bit()
{
	if (_andbits.empty()) {
		bc_logger().warn("Cannot fulfill an empty BIT");
		return;
	}

	// Select an and-BIT for fulfillment
	const AndBITFCMap::value_type& andbit = select_andbit();
	LAZY_BC_LOG_DEBUG << "Selected and-BIT for fulfillment:" << std::endl
	                  << andbit.second;
	fulfill_andbit(andbit);
}

void BackwardChainer::fulfill_andbit(const AndBITFCMap::value_type& andbit)
{
	Handle hresult = bindlink(&_as, andbit.second);
	const HandleSeq& results = hresult->getOutgoingSet();
	LAZY_BC_LOG_DEBUG << "Results:" << std::endl << results;
	_results.insert(results.begin(), results.end());
}

const AndBITFCMap::value_type& BackwardChainer::select_andbit()
{
	// For now selection is uniformly random
	return rand_element(_andbits);
}

BITNode& BackwardChainer::select_bitleaf(const AndBITFCMap::value_type& andbit)
{
	// For now selection is uniformly random
	return _handle2bitnode[rand_element(andbit.first)];
}

BITNode* BackwardChainer::select_target()
{
	if (_handle2bitnode.empty())
		return nullptr;

	// For now selection is uniformly random
	return &(rand_element(_handle2bitnode).second);
}

void BackwardChainer::reduce_bit()
{
	// TODO: avoid having the BIT grow arbitrarily large
}

Rule BackwardChainer::select_rule(const BITNode& target)
{
	// For now the rule is uniformly randomly selected amongst the
	// valid ones
	RuleSeq valid_rules = get_valid_rules(target);
	if (valid_rules.empty())
		return Rule();
	return rand_element(valid_rules);
}

RuleSeq BackwardChainer::get_valid_rules(const BITNode& target)
{
	RuleSeq valid_rules;
	for (const Rule& rule : _rules) {
		// Warning: the resulting rules are not added to _bit_as, this
		// is in order to work around the fact that atomspace would
		// consider alpha equivalent rules equal and thus rename the
		// variable names, which is then inconvenient when building
		// the forward chaining strategy because we have no garanty
		// that the variable names will be unique.
		//
		// It is likely that it is not the right way to do it. Instead
		// the fcs expansion code should make sure that the variable
		// names are unique while expanding.
		//
		// So this might be a temporary hack.
		RuleSeq unified_rules = rule.unify_target(target.body,
		                                          target.vardecl);//, &_bit_as);
		valid_rules.insert(valid_rules.end(),
		                   unified_rules.begin(), unified_rules.end());
	}
	return valid_rules;
}

void BackwardChainer::insert_h2b(Handle body, Handle vardecl,
                                 const BITFitness& fitness)
{
	if (body.is_undefined())
		return;

	// Make sure they are in the bit atomspace
	body = _bit_as.add_atom(body);
	vardecl = _bit_as.add_atom(vardecl);

	_handle2bitnode[body] = BITNode(body, vardecl, fitness);
}

void BackwardChainer::init_andbits()
{
	if (_init_target.is_undefined())
		return;

	HandleSeq bl{_init_target, _init_target};
	if (_init_vardecl.is_defined())
		bl.insert(bl.begin(), _init_vardecl);
	Handle fcs = _bit_as.add_link(BIND_LINK, bl);
	_andbits[{_init_target}] = fcs;
}

bool BackwardChainer::is_in(const Rule& rule, const BITNode& bitnode)
{
	for (const Rule& bnr : bitnode.rules)
		if (rule.is_alpha_equivalent(bnr))
			return true;
	return false;
}
<commit_msg>Simplify BackwardChainer rule atomspace management<commit_after>/*
 * BackwardChainer.cc
 *
 * Copyright (C) 2014-2016 OpenCog Foundation
 *
 * Authors: Misgana Bayetta <misgana.bayetta@gmail.com>  October 2014
 *          William Ma <https://github.com/williampma>
 *          Nil Geisweiller 2016
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <opencog/util/random.h>

#include <opencog/atomutils/FindUtils.h>
#include <opencog/atomutils/Substitutor.h>
#include <opencog/atomutils/Unify.h>
#include <opencog/atomutils/TypeUtils.h>
#include <opencog/atoms/pattern/PatternLink.h>
#include <opencog/atoms/pattern/BindLink.h>

#include <opencog/query/BindLinkAPI.h>

#include "BackwardChainer.h"
#include "BackwardChainerPMCB.h"
#include "UnifyPMCB.h"
#include "BCLogger.h"

using namespace opencog;

BackwardChainer::BackwardChainer(AtomSpace& as, const Handle& rbs,
                                 const Handle& htarget,
                                 const Handle& vardecl,
                                 const Handle& hfocus_set, // TODO:
                                                           // support
                                                           // focus_set
                                 const BITFitness& fitness)
	: _as(as), _configReader(as, rbs),
	  _init_target(htarget), _init_vardecl(vardecl), _init_fitness(fitness),
	  _bit_as(&as), _iteration(0), _rules(_configReader.get_rules()) {}

UREConfigReader& BackwardChainer::get_config()
{
	return _configReader;
}

const UREConfigReader& BackwardChainer::get_config() const
{
	return _configReader;
}

void BackwardChainer::do_chain()
{
	while (not termination())
	{
		do_step();
	}
}

void BackwardChainer::do_step()
{
	bc_logger().debug("Iteration %d", _iteration);
	_iteration++;

	expand_bit();
	fulfill_bit();
	reduce_bit();
}

bool BackwardChainer::termination()
{
	return _configReader.get_maximum_iterations() <= _iteration;
}

Handle BackwardChainer::get_results() const
{
	HandleSeq results(_results.begin(), _results.end());
	return _as.add_link(SET_LINK, results);
}

void BackwardChainer::expand_bit()
{
	if (_handle2bitnode.empty()) {
		// Initialize the and-BIT of the initial target
		insert_h2b(_init_target, _init_vardecl, _init_fitness);
		init_andbits();

		LAZY_BC_LOG_DEBUG << "Initialize BIT with:" << std::endl
		                  << _handle2bitnode[_init_target].to_string();
	} else {
		// Select an and-BIT and expand it
		const AndBITFCMap::value_type& andbit = select_andbit();
		LAZY_BC_LOG_DEBUG << "Selected and-BIT for expansion:" << std::endl
		                  << andbit.second;
		expand_bit(andbit);
	}
}

void BackwardChainer::expand_bit(const AndBITFCMap::value_type& andbit)
{
	// Select leaf
	BITNode& bitleaf = select_bitleaf(andbit);
	LAZY_BC_LOG_DEBUG << "Selected BIT-node for expansion:" << std::endl
	                  << bitleaf.to_string();

	// Select a valid rule
	Rule rule = select_rule(bitleaf);
	rule.add(_bit_as);
	if (not rule.is_valid()) {
		bc_logger().warn("No valid rule for the selected BIT-node, abort expansion");
		return;
	}
	LAZY_BC_LOG_DEBUG << "Selected rule for BIT expansion:" << std::endl
	                  << rule.to_string();

	// Expand the back-inference tree from this target
	expand_bit(andbit, bitleaf, rule);
}

void BackwardChainer::expand_bit(const AndBITFCMap::value_type& andbit,
                                 BITNode& bitleaf, const Rule& rule)
{
	// Make sure that the rule is not a or-child of leaf.
	if (is_in(rule, bitleaf)) {
		bc_logger().debug() << "An equivalent rule has already expanded that BIT-node, abort expansion";
		return;
	}

	// Expand the leaf
	// 1. Append the rule to it
	// 2. Instantiate the premises as BITNodes
	HandleSeq premises(rule.get_premises());
	bitleaf.rules.push_back(rule);
	for (const Handle& premise : premises)
		insert_h2b(premise, rule.get_forward_vardecl(), BITFitness());

	// Expand the associated atomese forward chaining strategy
	Handle fcs = expand_fcs(andbit.second, bitleaf.body, rule);

	// Define new and-BIT and associate new forward chaining strategy
	// to it
	AndBITFCMap::key_type new_leaves(andbit.first);
	new_leaves.erase(bitleaf.body);
	new_leaves.insert(premises.begin(), premises.end());
	_andbits[new_leaves] = fcs;
}

Handle BackwardChainer::expand_fcs(const Handle& fcs, const Handle& leaf,
                                   const Rule& rule)
{
	BindLinkPtr fcs_bl(BindLinkCast(fcs));
	Handle fcs_vardecl = fcs_bl->get_vardecl();
	Handle fcs_pattern = fcs_bl->get_body();
	Handle fcs_rewrite = fcs_bl->get_implicand();
	Handle rule_vardecl = rule.get_forward_vardecl();
	HandleSeq premises = rule.get_premises();
	Handle rule_rewrite = rule.get_forward_implicand();

	// Generate new pattern term
	Handle npattern = expand_fcs_pattern(fcs_pattern, leaf, premises);

	// Generate new rewrite term
	Handle nrewrite = expand_fcs_rewrite(fcs_rewrite, leaf, rule_rewrite);

	// Generate new vardecl
	Handle nvardecl = filter_vardecl(merge_vardecl(fcs_vardecl, rule_vardecl),
	                                 {npattern, nrewrite});

	// Generate new atomese forward chaining strategy
	HandleSeq noutgoings({npattern, nrewrite});
	if (nvardecl.is_defined())
		noutgoings.insert(noutgoings.begin(), nvardecl);
	Handle nfcs = _bit_as.add_link(BIND_LINK, noutgoings);

	LAZY_BC_LOG_DEBUG << "Expanded forward chainer strategy:" << std::endl << fcs
	                  << "to:" << std::endl << nfcs;

	return nfcs;
}

Handle BackwardChainer::expand_fcs_pattern(const Handle& fcs_pattern,
                                           const Handle& leaf,
                                           const HandleSeq& premises)
{
	if (fcs_pattern == leaf)
		return _bit_as.add_link(AND_LINK, premises);

	OC_ASSERT(fcs_pattern->getType() == AND_LINK);
	HandleSeq outgoings = fcs_pattern->getOutgoingSet();
	auto it = std::find(outgoings.begin(), outgoings.end(), leaf);
	OC_ASSERT(it != outgoings.end());
	outgoings.erase(it);
	outgoings.insert(outgoings.end(), premises.begin(), premises.end());
	return _bit_as.add_link(AND_LINK, outgoings);
}

Handle BackwardChainer::expand_fcs_rewrite(const Handle& fcs_rewrite,
                                           const Handle& leaf,
                                           const Handle& rule_rewrite)
{
	// Base cases

	// Replace the fcs rewrite atoms by the rule_rewrite if leaf
	if (fcs_rewrite == leaf)
		return rule_rewrite;
	// If node and isn't leaf leave alone
	if (fcs_rewrite->isNode())
		return fcs_rewrite;

	// Recursive case

	Type t = fcs_rewrite->getType();
	HandleSeq outgoings;
	for (const Handle& h : fcs_rewrite->getOutgoingSet())
		outgoings.push_back(expand_fcs_rewrite(h, leaf, rule_rewrite));
	return _bit_as.add_link(t, outgoings);
}

void BackwardChainer::fulfill_bit()
{
	if (_andbits.empty()) {
		bc_logger().warn("Cannot fulfill an empty BIT");
		return;
	}

	// Select an and-BIT for fulfillment
	const AndBITFCMap::value_type& andbit = select_andbit();
	LAZY_BC_LOG_DEBUG << "Selected and-BIT for fulfillment:" << std::endl
	                  << andbit.second;
	fulfill_andbit(andbit);
}

void BackwardChainer::fulfill_andbit(const AndBITFCMap::value_type& andbit)
{
	Handle hresult = bindlink(&_as, andbit.second);
	const HandleSeq& results = hresult->getOutgoingSet();
	LAZY_BC_LOG_DEBUG << "Results:" << std::endl << results;
	_results.insert(results.begin(), results.end());
}

const AndBITFCMap::value_type& BackwardChainer::select_andbit()
{
	// For now selection is uniformly random
	return rand_element(_andbits);
}

BITNode& BackwardChainer::select_bitleaf(const AndBITFCMap::value_type& andbit)
{
	// For now selection is uniformly random
	return _handle2bitnode[rand_element(andbit.first)];
}

BITNode* BackwardChainer::select_target()
{
	if (_handle2bitnode.empty())
		return nullptr;

	// For now selection is uniformly random
	return &(rand_element(_handle2bitnode).second);
}

void BackwardChainer::reduce_bit()
{
	// TODO: avoid having the BIT grow arbitrarily large
}

Rule BackwardChainer::select_rule(const BITNode& target)
{
	// For now the rule is uniformly randomly selected amongst the
	// valid ones
	RuleSeq valid_rules = get_valid_rules(target);
	if (valid_rules.empty())
		return Rule();
	return rand_element(valid_rules);
}

RuleSeq BackwardChainer::get_valid_rules(const BITNode& target)
{
	RuleSeq valid_rules;
	for (const Rule& rule : _rules) {
		RuleSeq unified_rules = rule.unify_target(target.body, target.vardecl);
		valid_rules.insert(valid_rules.end(),
		                   unified_rules.begin(), unified_rules.end());
	}
	return valid_rules;
}

void BackwardChainer::insert_h2b(Handle body, Handle vardecl,
                                 const BITFitness& fitness)
{
	if (body.is_undefined())
		return;

	_handle2bitnode[body] = BITNode(body, vardecl, fitness);
}

void BackwardChainer::init_andbits()
{
	if (_init_target.is_undefined())
		return;

	HandleSeq bl{_init_target, _init_target};
	if (_init_vardecl.is_defined())
		bl.insert(bl.begin(), _init_vardecl);
	Handle fcs = _bit_as.add_link(BIND_LINK, bl);
	_andbits[{_init_target}] = fcs;
}

bool BackwardChainer::is_in(const Rule& rule, const BITNode& bitnode)
{
	for (const Rule& bnr : bitnode.rules)
		if (rule.is_alpha_equivalent(bnr))
			return true;
	return false;
}
<|endoftext|>


<commit_before>#ifndef ELLIPTIC_PARAMETERS
#define ELLIPTIC_PARAMETERS

//*********************** Sets Number of subdivisions in X and Y direction *****************************************

#define NSUB_X  32
#define NSUB_Y  32

//*********************** Sets the regularization parameters *******************************************************
#define ALPHA_CTRL_BDRY 1.e-3
#define BETA_CTRL_BDRY 1.e-2

#define ALPHA_CTRL_VOL 1.e-3
#define BETA_CTRL_VOL 1.e-2

//*********************** Control box constraints *******************************************************
#define  INEQ_FLAG 1.
#define  C_COMPL 1.

 double InequalityConstraint(const std::vector<double> & dof_obj_coord, const bool upper) {

     double constr_value = 0.;
     double constr_value_upper = 1000.;//0.3; //0.2 + dof_obj_coord[0]*(1. - dof_obj_coord[0]);
     double constr_value_lower = -1000.; //-3.e-13;
     assert(constr_value_lower < constr_value_upper);

    if (upper)   constr_value = constr_value_upper;
    else         constr_value = constr_value_lower;

  return constr_value;

}

//*********************** Find volume elements that contain a  Target domain element **************************************

int ElementTargetFlag(const std::vector<double> & elem_center) {

 //***** set target domain flag ******
  int target_flag = 0; //set 0 to 1 to get the entire domain

  double target_line_sign;

        if (FACE_FOR_CONTROL == 3 || FACE_FOR_CONTROL == 2) { target_line_sign = -1; }
   else if (FACE_FOR_CONTROL == 1 || FACE_FOR_CONTROL == 4) { target_line_sign = 1;  }

   const double offset_to_include_line = 1.e-5;
   const double target_line = 0.5 + target_line_sign * offset_to_include_line;

      if (  target_line_sign * elem_center[1-AXIS_DIRECTION_CONTROL_SIDE] < target_line_sign * target_line ) {  target_flag = 1;  }

     return target_flag;

}

//******************************************* Desired Target *******************************************************

double DesiredTarget()
{
   return 1.;
}

//*********************** Find volume elements that contain a Control Face element *********************************

int ControlDomainFlag_bdry(const std::vector<double> & elem_center) {

  const double mesh_size = 1./NSUB_X;

  int control_el_flag = 0;

  const double offset_to_include_line = 1.e-5;

  double target_line_sign;
  double extreme_pos;

        if (FACE_FOR_CONTROL == 3 || FACE_FOR_CONTROL == 2) { target_line_sign = -1; extreme_pos = 1.; }
   else if (FACE_FOR_CONTROL == 1 || FACE_FOR_CONTROL == 4) { target_line_sign = 1;  extreme_pos = 0.; }

   if ( ( target_line_sign * elem_center[1-AXIS_DIRECTION_CONTROL_SIDE] <   target_line_sign * (  extreme_pos  + target_line_sign * mesh_size) )
/*       && ( elem_center[AXIS_DIRECTION_CONTROL_SIDE] > 0.25 - offset_to_include_line )
       && ( elem_center[AXIS_DIRECTION_CONTROL_SIDE] < 0.75 + offset_to_include_line ) */)
      { control_el_flag = 1; }

     return control_el_flag;
}

//*********************** Find volume elements that contain a Control domain element *********************************

int ControlDomainFlag_internal_restriction(const std::vector<double> & elem_center) {

 //***** set target domain flag ******
 // flag = 1: we are in the lifting nonzero domain
  int control_el_flag = 0.;

  const double offset_to_include_line = 1.e-5;

  double control_domain_width = 0.25;

  double target_line_sign;
  double extreme_pos;

        if (FACE_FOR_CONTROL == 3 || FACE_FOR_CONTROL == 2) { target_line_sign = -1; extreme_pos = 1.;}
   else if (FACE_FOR_CONTROL == 1 || FACE_FOR_CONTROL == 4) { target_line_sign = 1;  extreme_pos = 0.;}

   if ( ( target_line_sign * elem_center[1-AXIS_DIRECTION_CONTROL_SIDE] <   target_line_sign * ( extreme_pos + target_line_sign * control_domain_width ) )
 /*      && ( elem_center[AXIS_DIRECTION_CONTROL_SIDE] > 0.25 - offset_to_include_line )
       && ( elem_center[AXIS_DIRECTION_CONTROL_SIDE] < 0.75 + offset_to_include_line ) */)
      { control_el_flag = 1; }

     return control_el_flag;

}

//*********************** Find volume elements that contain a Control domain element *********************************

int ControlDomainFlag_external_restriction(const std::vector<double> & elem_center) {

 //***** set target domain flag ******
 // flag = 1: we are in the lifting nonzero domain
  int exterior_el_flag = 0.;
   if ( elem_center[0] >  1. -  1.e-5) { exterior_el_flag = 1; }

     return exterior_el_flag;

}

#endif
<commit_msg>Changed the Target domain for the external lift restriction problem<commit_after>#ifndef ELLIPTIC_PARAMETERS
#define ELLIPTIC_PARAMETERS

//*********************** Sets Number of subdivisions in X and Y direction *****************************************

#define NSUB_X  32
#define NSUB_Y  32

//*********************** Sets the regularization parameters *******************************************************
#define ALPHA_CTRL_BDRY 1.e-3
#define BETA_CTRL_BDRY 1.e-2

#define ALPHA_CTRL_VOL 1.e-3
#define BETA_CTRL_VOL 1.e-2

//*********************** Control box constraints *******************************************************
#define  INEQ_FLAG 1.
#define  C_COMPL 1.

 double InequalityConstraint(const std::vector<double> & dof_obj_coord, const bool upper) {

     double constr_value = 0.;
     double constr_value_upper = 1000.;//0.3; //0.2 + dof_obj_coord[0]*(1. - dof_obj_coord[0]);
     double constr_value_lower = -1000.; //-3.e-13;
     assert(constr_value_lower < constr_value_upper);

    if (upper)   constr_value = constr_value_upper;
    else         constr_value = constr_value_lower;

  return constr_value;

}

//*********************** Find volume elements that contain a  Target domain element **************************************

int ElementTargetFlag(const std::vector<double> & elem_center) {

 //***** set target domain flag ******
  int target_flag = 0; //set 0 to 1 to get the entire domain

  double target_line_sign;

        if (FACE_FOR_CONTROL == 3 || FACE_FOR_CONTROL == 2) { target_line_sign = -1; }
   else if (FACE_FOR_CONTROL == 1 || FACE_FOR_CONTROL == 4) { target_line_sign = 1;  }

   const double offset_to_include_line = 1.e-5;
   const double target_line = 0.5 + target_line_sign * offset_to_include_line;

      if ((  target_line_sign * elem_center[1-AXIS_DIRECTION_CONTROL_SIDE] < target_line_sign * target_line ) &&
          (  target_line_sign * elem_center[1-AXIS_DIRECTION_CONTROL_SIDE] > - 0.5 + target_line_sign * (0.5 - target_line_sign * offset_to_include_line)))
          {  target_flag = 1;  }

     return target_flag;

}

//******************************************* Desired Target *******************************************************

double DesiredTarget()
{
   return 1.;
}

//*********************** Find volume elements that contain a Control Face element *********************************

int ControlDomainFlag_bdry(const std::vector<double> & elem_center) {

  const double mesh_size = 1./NSUB_X;

  int control_el_flag = 0;

  const double offset_to_include_line = 1.e-5;

  double target_line_sign;
  double extreme_pos;

        if (FACE_FOR_CONTROL == 3 || FACE_FOR_CONTROL == 2) { target_line_sign = -1; extreme_pos = 1.; }
   else if (FACE_FOR_CONTROL == 1 || FACE_FOR_CONTROL == 4) { target_line_sign = 1;  extreme_pos = 0.; }

   if ( ( target_line_sign * elem_center[1-AXIS_DIRECTION_CONTROL_SIDE] <   target_line_sign * (  extreme_pos  + target_line_sign * mesh_size) )
/*       && ( elem_center[AXIS_DIRECTION_CONTROL_SIDE] > 0.25 - offset_to_include_line )
       && ( elem_center[AXIS_DIRECTION_CONTROL_SIDE] < 0.75 + offset_to_include_line ) */)
      { control_el_flag = 1; }

     return control_el_flag;
}

//*********************** Find volume elements that contain a Control domain element *********************************

int ControlDomainFlag_internal_restriction(const std::vector<double> & elem_center) {

 //***** set target domain flag ******
 // flag = 1: we are in the lifting nonzero domain
  int control_el_flag = 0.;

  const double offset_to_include_line = 1.e-5;

  double control_domain_width = 0.25;

  double target_line_sign;
  double extreme_pos;

        if (FACE_FOR_CONTROL == 3 || FACE_FOR_CONTROL == 2) { target_line_sign = -1; extreme_pos = 1.;}
   else if (FACE_FOR_CONTROL == 1 || FACE_FOR_CONTROL == 4) { target_line_sign = 1;  extreme_pos = 0.;}

   if ( ( target_line_sign * elem_center[1-AXIS_DIRECTION_CONTROL_SIDE] <   target_line_sign * ( extreme_pos + target_line_sign * control_domain_width ) )
 /*      && ( elem_center[AXIS_DIRECTION_CONTROL_SIDE] > 0.25 - offset_to_include_line )
       && ( elem_center[AXIS_DIRECTION_CONTROL_SIDE] < 0.75 + offset_to_include_line ) */)
      { control_el_flag = 1; }

     return control_el_flag;

}

//*********************** Find volume elements that contain a Control domain element *********************************

int ControlDomainFlag_external_restriction(const std::vector<double> & elem_center) {

 //***** set target domain flag ******
 // flag = 1: we are in the lifting nonzero domain
  int exterior_el_flag = 0.;
   if ( elem_center[0] >  1. -  1.e-5) { exterior_el_flag = 1; }

     return exterior_el_flag;

}

#endif
<|endoftext|>