<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef SC_XCLIMPCHANGETRACK_HXX
#define SC_XCLIMPCHANGETRACK_HXX

#include <tools/datetime.hxx>
#include "xiroot.hxx"
#include "xistream.hxx"
#include "excform.hxx"
#include "imp_op.hxx"

//___________________________________________________________________

class ScCellValue;
class ScChangeAction;
class ScChangeTrack;
class XclImpChTrFmlConverter;

//___________________________________________________________________

struct XclImpChTrRecHeader
{
    sal_uInt32                  nSize;
    sal_uInt32                  nIndex;
    sal_uInt16                  nOpCode;
    sal_uInt16                  nAccept;
};

inline XclImpStream& operator>>( XclImpStream& rStrm, XclImpChTrRecHeader& rRecHeader )
{
    rStrm >> rRecHeader.nSize >> rRecHeader.nIndex >> rRecHeader.nOpCode >> rRecHeader.nAccept;
    return rStrm;
}

//___________________________________________________________________

class XclImpChangeTrack : protected XclImpRoot
{
private:
    XclImpChTrRecHeader         aRecHeader;
    String                      sOldUsername;

    ScChangeTrack*              pChangeTrack;
    SotStorageStreamRef          xInStrm;        // input stream
    XclImpStream*               pStrm;          // stream import class
    sal_uInt16                  nTabIdCount;
    sal_Bool                    bGlobExit;      // global exit loop

    enum { nmBase, nmFound, nmNested }
                                eNestedMode;    // action with nested content actions

    inline sal_Bool             FoundNestedMode() { return eNestedMode == nmFound; }

    void                        DoAcceptRejectAction( ScChangeAction* pAction );
    void                        DoAcceptRejectAction( sal_uInt32 nFirst, sal_uInt32 nLast );

    void                        DoInsertRange( const ScRange& rRange );
    void                        DoDeleteRange( const ScRange& rRange );

    inline sal_uInt8            LookAtuInt8();
    inline double               ReadRK();
    inline sal_Bool             ReadBool();
    inline void                 Read2DAddress( ScAddress& rAddress );
    inline void                 Read2DRange( ScRange& rRange );
    SCTAB                       ReadTabNum();
    void                        ReadDateTime( DateTime& rDateTime );

    inline void                 ReadString( String& rString );

    sal_Bool                    CheckRecord( sal_uInt16 nOpCode );

    void                        ReadFormula(
                                    ScTokenArray*& rpTokenArray,
                                    const ScAddress& rPosition );
    void ReadCell( ScCellValue& rCell, sal_uInt32& rFormat, sal_uInt16 nFlags, const ScAddress& rPosition );

    void                        ReadChTrInsert();           // 0x0137
    void                        ReadChTrInfo();             // 0x0138
    void                        ReadChTrCellContent();      // 0x013B
    void                        ReadChTrTabId();            // 0x013D
    void                        ReadChTrMoveRange();        // 0x0140
    void                        ReadChTrInsertTab();        // 0x014D
    void                        InitNestedMode();           // 0x014E, 0x0150
    void                        ReadNestedRecords();
    sal_Bool                    EndNestedMode();            // 0x014F, 0x0151

    void                        ReadRecords();

public:
                                XclImpChangeTrack( const XclImpRoot& rRoot, const XclImpStream& rBookStrm );
                                ~XclImpChangeTrack();

                                // reads extended 3D ref info following the formulas, returns sc tab nums
                                // ( called by XclImpChTrFmlConverter::Read3DTabReference() )
    sal_Bool                    Read3DTabRefInfo( SCTAB& rFirstTab, SCTAB& rLastTab, ExcelToSc8::ExternalTabInfo& rExtInfo );

    void                        Apply();
};

inline sal_uInt8 XclImpChangeTrack::LookAtuInt8()
{
    pStrm->PushPosition();
    sal_uInt8 nValue;
    *pStrm >> nValue;
    pStrm->PopPosition();
    return nValue;
}

inline double XclImpChangeTrack::ReadRK()
{
    return XclTools::GetDoubleFromRK( pStrm->ReadInt32() );
}

inline sal_Bool XclImpChangeTrack::ReadBool()
{
    return (pStrm->ReaduInt16() != 0);
}

inline void XclImpChangeTrack::Read2DAddress( ScAddress& rAddress )
{
    rAddress.SetRow( static_cast<SCROW>(pStrm->ReaduInt16()) );
    rAddress.SetCol( static_cast<SCCOL>(pStrm->ReaduInt16()) );
}

inline void XclImpChangeTrack::Read2DRange( ScRange& rRange )
{
    rRange.aStart.SetRow( static_cast<SCROW>(pStrm->ReaduInt16()) );
    rRange.aEnd.SetRow( static_cast<SCROW>(pStrm->ReaduInt16()) );
    rRange.aStart.SetCol( static_cast<SCCOL>(pStrm->ReaduInt16()) );
    rRange.aEnd.SetCol( static_cast<SCCOL>(pStrm->ReaduInt16()) );
}

inline void XclImpChangeTrack::ReadString( String& rString )
{
    rString = pStrm->ReadUniString();
}

//___________________________________________________________________
// derived class for special 3D ref handling

class XclImpChTrFmlConverter : public ExcelToSc8
{
private:
    XclImpChangeTrack&          rChangeTrack;

    virtual bool                Read3DTabReference( sal_uInt16 nIxti, SCTAB& rFirstTab, SCTAB& rLastTab, ExternalTabInfo& rExtInfo );

public:
    inline                      XclImpChTrFmlConverter(
                                    const XclImpRoot& rRoot,
                                    XclImpChangeTrack& rXclChTr );
    virtual                     ~XclImpChTrFmlConverter();
};

inline XclImpChTrFmlConverter::XclImpChTrFmlConverter(
        const XclImpRoot& rRoot,
        XclImpChangeTrack& rXclChTr ) :
    ExcelToSc8( rRoot ),
    rChangeTrack( rXclChTr )
{
}

//___________________________________________________________________

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>WaE: 'ScCellValue' defined as a struct here but previously declared as a class<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef SC_XCLIMPCHANGETRACK_HXX
#define SC_XCLIMPCHANGETRACK_HXX

#include <tools/datetime.hxx>
#include "xiroot.hxx"
#include "xistream.hxx"
#include "excform.hxx"
#include "imp_op.hxx"

//___________________________________________________________________

struct ScCellValue;
class ScChangeAction;
class ScChangeTrack;
class XclImpChTrFmlConverter;

//___________________________________________________________________

struct XclImpChTrRecHeader
{
    sal_uInt32                  nSize;
    sal_uInt32                  nIndex;
    sal_uInt16                  nOpCode;
    sal_uInt16                  nAccept;
};

inline XclImpStream& operator>>( XclImpStream& rStrm, XclImpChTrRecHeader& rRecHeader )
{
    rStrm >> rRecHeader.nSize >> rRecHeader.nIndex >> rRecHeader.nOpCode >> rRecHeader.nAccept;
    return rStrm;
}

//___________________________________________________________________

class XclImpChangeTrack : protected XclImpRoot
{
private:
    XclImpChTrRecHeader         aRecHeader;
    String                      sOldUsername;

    ScChangeTrack*              pChangeTrack;
    SotStorageStreamRef          xInStrm;        // input stream
    XclImpStream*               pStrm;          // stream import class
    sal_uInt16                  nTabIdCount;
    sal_Bool                    bGlobExit;      // global exit loop

    enum { nmBase, nmFound, nmNested }
                                eNestedMode;    // action with nested content actions

    inline sal_Bool             FoundNestedMode() { return eNestedMode == nmFound; }

    void                        DoAcceptRejectAction( ScChangeAction* pAction );
    void                        DoAcceptRejectAction( sal_uInt32 nFirst, sal_uInt32 nLast );

    void                        DoInsertRange( const ScRange& rRange );
    void                        DoDeleteRange( const ScRange& rRange );

    inline sal_uInt8            LookAtuInt8();
    inline double               ReadRK();
    inline sal_Bool             ReadBool();
    inline void                 Read2DAddress( ScAddress& rAddress );
    inline void                 Read2DRange( ScRange& rRange );
    SCTAB                       ReadTabNum();
    void                        ReadDateTime( DateTime& rDateTime );

    inline void                 ReadString( String& rString );

    sal_Bool                    CheckRecord( sal_uInt16 nOpCode );

    void                        ReadFormula(
                                    ScTokenArray*& rpTokenArray,
                                    const ScAddress& rPosition );
    void ReadCell( ScCellValue& rCell, sal_uInt32& rFormat, sal_uInt16 nFlags, const ScAddress& rPosition );

    void                        ReadChTrInsert();           // 0x0137
    void                        ReadChTrInfo();             // 0x0138
    void                        ReadChTrCellContent();      // 0x013B
    void                        ReadChTrTabId();            // 0x013D
    void                        ReadChTrMoveRange();        // 0x0140
    void                        ReadChTrInsertTab();        // 0x014D
    void                        InitNestedMode();           // 0x014E, 0x0150
    void                        ReadNestedRecords();
    sal_Bool                    EndNestedMode();            // 0x014F, 0x0151

    void                        ReadRecords();

public:
                                XclImpChangeTrack( const XclImpRoot& rRoot, const XclImpStream& rBookStrm );
                                ~XclImpChangeTrack();

                                // reads extended 3D ref info following the formulas, returns sc tab nums
                                // ( called by XclImpChTrFmlConverter::Read3DTabReference() )
    sal_Bool                    Read3DTabRefInfo( SCTAB& rFirstTab, SCTAB& rLastTab, ExcelToSc8::ExternalTabInfo& rExtInfo );

    void                        Apply();
};

inline sal_uInt8 XclImpChangeTrack::LookAtuInt8()
{
    pStrm->PushPosition();
    sal_uInt8 nValue;
    *pStrm >> nValue;
    pStrm->PopPosition();
    return nValue;
}

inline double XclImpChangeTrack::ReadRK()
{
    return XclTools::GetDoubleFromRK( pStrm->ReadInt32() );
}

inline sal_Bool XclImpChangeTrack::ReadBool()
{
    return (pStrm->ReaduInt16() != 0);
}

inline void XclImpChangeTrack::Read2DAddress( ScAddress& rAddress )
{
    rAddress.SetRow( static_cast<SCROW>(pStrm->ReaduInt16()) );
    rAddress.SetCol( static_cast<SCCOL>(pStrm->ReaduInt16()) );
}

inline void XclImpChangeTrack::Read2DRange( ScRange& rRange )
{
    rRange.aStart.SetRow( static_cast<SCROW>(pStrm->ReaduInt16()) );
    rRange.aEnd.SetRow( static_cast<SCROW>(pStrm->ReaduInt16()) );
    rRange.aStart.SetCol( static_cast<SCCOL>(pStrm->ReaduInt16()) );
    rRange.aEnd.SetCol( static_cast<SCCOL>(pStrm->ReaduInt16()) );
}

inline void XclImpChangeTrack::ReadString( String& rString )
{
    rString = pStrm->ReadUniString();
}

//___________________________________________________________________
// derived class for special 3D ref handling

class XclImpChTrFmlConverter : public ExcelToSc8
{
private:
    XclImpChangeTrack&          rChangeTrack;

    virtual bool                Read3DTabReference( sal_uInt16 nIxti, SCTAB& rFirstTab, SCTAB& rLastTab, ExternalTabInfo& rExtInfo );

public:
    inline                      XclImpChTrFmlConverter(
                                    const XclImpRoot& rRoot,
                                    XclImpChangeTrack& rXclChTr );
    virtual                     ~XclImpChTrFmlConverter();
};

inline XclImpChTrFmlConverter::XclImpChTrFmlConverter(
        const XclImpRoot& rRoot,
        XclImpChangeTrack& rXclChTr ) :
    ExcelToSc8( rRoot ),
    rChangeTrack( rXclChTr )
{
}

//___________________________________________________________________

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/* The libMesh Finite Element Library. */
/* Copyright (C) 2003  Benjamin S. Kirk */

/* 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

//
Miscellaneous Example 8 - Meshfree Interpolation Utilities.

//
// LibMesh provides some utilities for pointcloud-type interpolation, as
// demonstrated in this example.

// Example include files
#include "libmesh/libmesh.h"
#include "libmesh/meshfree_interpolation.h"
#include "libmesh/radial_basis_interpolation.h"
#include "libmesh/mesh.h"
#include "libmesh/equation_systems.h"
#include "libmesh/numeric_vector.h"
#include "libmesh/tecplot_io.h"
#include "libmesh/threads.h"
#include "meshless_interpolation_function.h"

// C++ includes
#include <cstdlib>

// Bring in everything from the libMesh namespace
using namespace libMesh;

void create_random_point_cloud (const unsigned int Npts,
				std::vector<Point> &pts,
				const Real max_range = 10)
{
  std::cout << "Generating "<< Npts << " point cloud...";
  pts.resize(Npts);

  for (size_t i=0;i<Npts;i++)
    {
      pts[i](0) = max_range * (std::rand() % 1000) / Real(1000);
      pts[i](1) = max_range * (std::rand() % 1000) / Real(1000);
      pts[i](2) = max_range * (std::rand() % 1000) / Real(1000);
    }
  std::cout << "done\n";
}

Real exact_solution_u (const Point &p)
{
  const Real
    x = p(0),
    y = p(1),
    z = p(2);

  return (x*x*x   +
	  y*y*y*y +
	  z*z*z*z*z);
}

Real exact_solution_v (const Point &p)
{
  const Real
    x = p(0),
    y = p(1),
    z = p(2);

  return (x*x   +
	  y*y +
	  z*z*z);
}

Number exact_value (const Point& p,
                    const Parameters&,
                    const std::string&,
                    const std::string&)
{
  return exact_solution_v(p);
}

// We now define the function which provides the
// initialization routines for the "Convection-Diffusion"
// system.  This handles things like setting initial
// conditions and boundary conditions.
void init_sys(EquationSystems& es,
              const std::string& system_name)
{
  // Get a reference to the Convection-Diffusion system object.
  System & system =
    es.get_system<System>(system_name);

  system.project_solution(exact_value, NULL, es.parameters);
}

int main(int argc, char** argv)
{
  // Skip this example if we do not meet certain requirements
  libmesh_example_assert(3 <= LIBMESH_DIM, "3D support");
#ifndef LIBMESH_HAVE_EIGEN
  libmesh_example_assert(false, "--enable-eigen");
#endif
#ifndef LIBMESH_HAVE_ZLIB_H
  libmesh_example_assert(false, "--enable-zlib");
#endif

  // Initialize libMesh.
  LibMeshInit init (argc, argv);
  {
    // Demonstration case 1
    {
      std::vector<Point>       tgt_pts;
      std::vector<Number>      tgt_data_idi, tgt_data_rbi;
      std::vector<std::string> field_vars;

      field_vars.push_back("u");
      field_vars.push_back("v");

      InverseDistanceInterpolation<3> idi (/* n_interp_pts = */ 8,
					   /* power =        */ 2);

      RadialBasisInterpolation<3> rbi;

      idi.set_field_variables (field_vars);
      rbi.set_field_variables (field_vars);

      create_random_point_cloud (100,
				 idi.get_source_points());

      // Explicitly set the data values we will interpolate from
      {
	const std::vector<Point> &src_pts  (idi.get_source_points());
	std::vector<Number>      &src_vals (idi.get_source_vals());

	src_vals.clear(); src_vals.reserve(2*src_pts.size());

	for (std::vector<Point>::const_iterator pt_it=src_pts.begin();
	     pt_it != src_pts.end(); ++pt_it)
	  {
	    src_vals.push_back (exact_solution_u (*pt_it));
	    src_vals.push_back (exact_solution_v (*pt_it));
	  }
      }

      // give rbi the same info as idi
      rbi.get_source_points() = idi.get_source_points();
      rbi.get_source_vals()   = idi.get_source_vals();

      idi.prepare_for_use();
      rbi.prepare_for_use();

      std::cout << idi;

      // Interpolate to some other random points, and evaluate the result
      {
	create_random_point_cloud (10,
				   tgt_pts);

	//tgt_pts = rbi.get_source_points();

	idi.interpolate_field_data (field_vars,
				    tgt_pts,
				    tgt_data_idi);

	rbi.interpolate_field_data (field_vars,
				    tgt_pts,
				    tgt_data_rbi);

      	std::vector<Number>::const_iterator
	  v_idi=tgt_data_idi.begin(),
	  v_rbi=tgt_data_rbi.begin();

	for (std::vector<Point>::const_iterator  p_it=tgt_pts.begin();
	     p_it!=tgt_pts.end(); ++p_it)
	  {
	    std::cout << "\nAt target point " << *p_it
		      << "\n u_interp_idi="   << *v_idi
		      << ", u_interp_rbi="    << *v_rbi
		      << ", u_exact="         << exact_solution_u(*p_it);
	    ++v_idi;
	    ++v_rbi;
	    std::cout << "\n v_interp_idi=" << *v_idi
		      << ", v_interp_rbi="  << *v_rbi
		      << ", v_exact="       << exact_solution_v(*p_it)
		      << std::endl;
	    ++v_idi;
	    ++v_rbi;
	  }
      }
    }

    // Demonstration case 2
    {
      Mesh mesh_a(init.communicator()), mesh_b(init.communicator());

      mesh_a.read("struct.ucd.gz"); mesh_b.read("unstruct.ucd.gz");

      // Create equation systems objects.
      EquationSystems
	es_a(mesh_a), es_b(mesh_b);

      System
	&sys_a = es_a.add_system<System>("src_system"),
	&sys_b = es_b.add_system<System>("dest_system");

      sys_a.add_variable ("Cp", FIRST);
      sys_b.add_variable ("Cp", FIRST);

      sys_a.attach_init_function (init_sys);
      es_a.init();

      // Write out the initial conditions.
      TecplotIO(mesh_a).write_equation_systems ("src.dat",
						es_a);

      InverseDistanceInterpolation<3> idi (/* n_interp_pts = */ 4,
					   /* power =        */ 2);
      RadialBasisInterpolation<3> rbi;

      std::vector<Point>  &src_pts  (idi.get_source_points());
      std::vector<Number> &src_vals (idi.get_source_vals());
      std::vector<std::string> field_vars;
      field_vars.push_back("Cp");
      idi.set_field_variables(field_vars);

      // We now will loop over every node in the source mesh
      // and add it to a source point list, along with the solution
      {
	MeshBase::const_node_iterator nd  = mesh_a.local_nodes_begin();
	MeshBase::const_node_iterator end = mesh_a.local_nodes_end();

	for (; nd!=end; ++nd)
	  {
	    const Node *node(*nd);
	    src_pts.push_back(*node);
	    src_vals.push_back(sys_a.current_solution(node->dof_number(0,0,0)));
	  }

	rbi.set_field_variables(field_vars);
	rbi.get_source_points() = idi.get_source_points();
	rbi.get_source_vals()   = idi.get_source_vals();
      }

      // We have only set local values - prepare for use by gathering remote gata
      idi.prepare_for_use();
      rbi.prepare_for_use();

      // Create a MeshlessInterpolationFunction that uses our InverseDistanceInterpolation
      // object.  Since each MeshlessInterpolationFunction shares the same InverseDistanceInterpolation
      // object in a threaded environment we must also provide a locking mechanism.
      {
	Threads::spin_mutex mutex;
	MeshlessInterpolationFunction mif(idi, mutex);

	// project the solution onto system b
	es_b.init();
	sys_b.project_solution (&mif);

	// Write the result
	TecplotIO(mesh_b).write_equation_systems ("dest_idi.dat",
						  es_b);
      }

      // Create a MeshlessInterpolationFunction that uses our RadialBasisInterpolation
      // object.  Since each MeshlessInterpolationFunction shares the same RadialBasisInterpolation
      // object in a threaded environment we must also provide a locking mechanism.
      {
	Threads::spin_mutex mutex;
	MeshlessInterpolationFunction mif(rbi, mutex);

	// project the solution onto system b
	sys_b.project_solution (&mif);

	// Write the result
	TecplotIO(mesh_b).write_equation_systems ("dest_rbi.dat",
						  es_b);
      }
    }

  }
  return 0;
}
<commit_msg>miscellaneous_ex8 constructor API compatibility<commit_after>/* The libMesh Finite Element Library. */
/* Copyright (C) 2003  Benjamin S. Kirk */

/* 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

//
Miscellaneous Example 8 - Meshfree Interpolation Utilities.

//
// LibMesh provides some utilities for pointcloud-type interpolation, as
// demonstrated in this example.

// Example include files
#include "libmesh/libmesh.h"
#include "libmesh/meshfree_interpolation.h"
#include "libmesh/radial_basis_interpolation.h"
#include "libmesh/mesh.h"
#include "libmesh/equation_systems.h"
#include "libmesh/numeric_vector.h"
#include "libmesh/tecplot_io.h"
#include "libmesh/threads.h"
#include "meshless_interpolation_function.h"

// C++ includes
#include <cstdlib>

// Bring in everything from the libMesh namespace
using namespace libMesh;

void create_random_point_cloud (const unsigned int Npts,
				std::vector<Point> &pts,
				const Real max_range = 10)
{
  std::cout << "Generating "<< Npts << " point cloud...";
  pts.resize(Npts);

  for (size_t i=0;i<Npts;i++)
    {
      pts[i](0) = max_range * (std::rand() % 1000) / Real(1000);
      pts[i](1) = max_range * (std::rand() % 1000) / Real(1000);
      pts[i](2) = max_range * (std::rand() % 1000) / Real(1000);
    }
  std::cout << "done\n";
}

Real exact_solution_u (const Point &p)
{
  const Real
    x = p(0),
    y = p(1),
    z = p(2);

  return (x*x*x   +
	  y*y*y*y +
	  z*z*z*z*z);
}

Real exact_solution_v (const Point &p)
{
  const Real
    x = p(0),
    y = p(1),
    z = p(2);

  return (x*x   +
	  y*y +
	  z*z*z);
}

Number exact_value (const Point& p,
                    const Parameters&,
                    const std::string&,
                    const std::string&)
{
  return exact_solution_v(p);
}

// We now define the function which provides the
// initialization routines for the "Convection-Diffusion"
// system.  This handles things like setting initial
// conditions and boundary conditions.
void init_sys(EquationSystems& es,
              const std::string& system_name)
{
  // Get a reference to the Convection-Diffusion system object.
  System & system =
    es.get_system<System>(system_name);

  system.project_solution(exact_value, NULL, es.parameters);
}

int main(int argc, char** argv)
{
  // Skip this example if we do not meet certain requirements
  libmesh_example_assert(3 <= LIBMESH_DIM, "3D support");
#ifndef LIBMESH_HAVE_EIGEN
  libmesh_example_assert(false, "--enable-eigen");
#endif
#ifndef LIBMESH_HAVE_ZLIB_H
  libmesh_example_assert(false, "--enable-zlib");
#endif

  // Initialize libMesh.
  LibMeshInit init (argc, argv);
  {
    // Demonstration case 1
    {
      std::vector<Point>       tgt_pts;
      std::vector<Number>      tgt_data_idi, tgt_data_rbi;
      std::vector<std::string> field_vars;

      field_vars.push_back("u");
      field_vars.push_back("v");

      InverseDistanceInterpolation<3> idi (init.communicator(),
					   /* n_interp_pts = */ 8,
					   /* power =        */ 2);

      RadialBasisInterpolation<3> rbi (init.communicator());

      idi.set_field_variables (field_vars);
      rbi.set_field_variables (field_vars);

      create_random_point_cloud (100,
				 idi.get_source_points());

      // Explicitly set the data values we will interpolate from
      {
	const std::vector<Point> &src_pts  (idi.get_source_points());
	std::vector<Number>      &src_vals (idi.get_source_vals());

	src_vals.clear(); src_vals.reserve(2*src_pts.size());

	for (std::vector<Point>::const_iterator pt_it=src_pts.begin();
	     pt_it != src_pts.end(); ++pt_it)
	  {
	    src_vals.push_back (exact_solution_u (*pt_it));
	    src_vals.push_back (exact_solution_v (*pt_it));
	  }
      }

      // give rbi the same info as idi
      rbi.get_source_points() = idi.get_source_points();
      rbi.get_source_vals()   = idi.get_source_vals();

      idi.prepare_for_use();
      rbi.prepare_for_use();

      std::cout << idi;

      // Interpolate to some other random points, and evaluate the result
      {
	create_random_point_cloud (10,
				   tgt_pts);

	//tgt_pts = rbi.get_source_points();

	idi.interpolate_field_data (field_vars,
				    tgt_pts,
				    tgt_data_idi);

	rbi.interpolate_field_data (field_vars,
				    tgt_pts,
				    tgt_data_rbi);

      	std::vector<Number>::const_iterator
	  v_idi=tgt_data_idi.begin(),
	  v_rbi=tgt_data_rbi.begin();

	for (std::vector<Point>::const_iterator  p_it=tgt_pts.begin();
	     p_it!=tgt_pts.end(); ++p_it)
	  {
	    std::cout << "\nAt target point " << *p_it
		      << "\n u_interp_idi="   << *v_idi
		      << ", u_interp_rbi="    << *v_rbi
		      << ", u_exact="         << exact_solution_u(*p_it);
	    ++v_idi;
	    ++v_rbi;
	    std::cout << "\n v_interp_idi=" << *v_idi
		      << ", v_interp_rbi="  << *v_rbi
		      << ", v_exact="       << exact_solution_v(*p_it)
		      << std::endl;
	    ++v_idi;
	    ++v_rbi;
	  }
      }
    }

    // Demonstration case 2
    {
      Mesh mesh_a(init.communicator()), mesh_b(init.communicator());

      mesh_a.read("struct.ucd.gz"); mesh_b.read("unstruct.ucd.gz");

      // Create equation systems objects.
      EquationSystems
	es_a(mesh_a), es_b(mesh_b);

      System
	&sys_a = es_a.add_system<System>("src_system"),
	&sys_b = es_b.add_system<System>("dest_system");

      sys_a.add_variable ("Cp", FIRST);
      sys_b.add_variable ("Cp", FIRST);

      sys_a.attach_init_function (init_sys);
      es_a.init();

      // Write out the initial conditions.
      TecplotIO(mesh_a).write_equation_systems ("src.dat",
						es_a);

      InverseDistanceInterpolation<3> idi (init.communicator(),
					   /* n_interp_pts = */ 4,
					   /* power =        */ 2);
      RadialBasisInterpolation<3> rbi (init.communicator());

      std::vector<Point>  &src_pts  (idi.get_source_points());
      std::vector<Number> &src_vals (idi.get_source_vals());
      std::vector<std::string> field_vars;
      field_vars.push_back("Cp");
      idi.set_field_variables(field_vars);

      // We now will loop over every node in the source mesh
      // and add it to a source point list, along with the solution
      {
	MeshBase::const_node_iterator nd  = mesh_a.local_nodes_begin();
	MeshBase::const_node_iterator end = mesh_a.local_nodes_end();

	for (; nd!=end; ++nd)
	  {
	    const Node *node(*nd);
	    src_pts.push_back(*node);
	    src_vals.push_back(sys_a.current_solution(node->dof_number(0,0,0)));
	  }

	rbi.set_field_variables(field_vars);
	rbi.get_source_points() = idi.get_source_points();
	rbi.get_source_vals()   = idi.get_source_vals();
      }

      // We have only set local values - prepare for use by gathering remote gata
      idi.prepare_for_use();
      rbi.prepare_for_use();

      // Create a MeshlessInterpolationFunction that uses our InverseDistanceInterpolation
      // object.  Since each MeshlessInterpolationFunction shares the same InverseDistanceInterpolation
      // object in a threaded environment we must also provide a locking mechanism.
      {
	Threads::spin_mutex mutex;
	MeshlessInterpolationFunction mif(idi, mutex);

	// project the solution onto system b
	es_b.init();
	sys_b.project_solution (&mif);

	// Write the result
	TecplotIO(mesh_b).write_equation_systems ("dest_idi.dat",
						  es_b);
      }

      // Create a MeshlessInterpolationFunction that uses our RadialBasisInterpolation
      // object.  Since each MeshlessInterpolationFunction shares the same RadialBasisInterpolation
      // object in a threaded environment we must also provide a locking mechanism.
      {
	Threads::spin_mutex mutex;
	MeshlessInterpolationFunction mif(rbi, mutex);

	// project the solution onto system b
	sys_b.project_solution (&mif);

	// Write the result
	TecplotIO(mesh_b).write_equation_systems ("dest_rbi.dat",
						  es_b);
      }
    }

  }
  return 0;
}
<|endoftext|>


<commit_before><commit_msg>translation to C: name mangling for scope-local classes<commit_after><|endoftext|>


<commit_before>#include "main.h"
#include "viewer.h"
#include "lang_val.h"
#include "registry.h"
#include "config.h"
#include "illa/codecmgr.h"
#include "orz/intl.h"
#include "control.h"
#include "w32_assure_folder.h"
#include "orz/logger.h"

int start_app(const std::string& params) {
	if (params == "--cleanup") {
		// If the user refused to uninstall the previous version when upgrading, the uninstaller will likely call pictus.exe with --cleanup
		// as parameter. Let's not throw up a blank Pictus windows in that situation.
		// This applies when 1.1.4.0 or older was installed.
		return EXIT_SUCCESS;
	}

	Img::CodecFactoryStore cfs;
	cfs.AddBuiltinCodecs();

	try {
		auto cfg = Reg::Load(App::cg_SettingsLocation);

		// TODO: Control logging by some other mechanism, such as an .ini setting
		Log.SetOutput(assure_folder(App::cg_RunLogLocation));

		Intl::LanguageTable(c_lang_strings);
		Intl::CurrentLanguage(cfg.View.Language);

		App::Viewer viewer(&cfs, cfg, params.c_str());

		// Attempt to display viewer
		if (viewer.Create(0)) {
			viewer.Show(true);
		}

		viewer.StartApplication();
	}
	catch(Err::DuplicateInstance&) {
		// This is not something out of the ordinary.
	}
	catch(Err::Exception& e) {
		Log << "Exception caught:\n" << e.what() << "\n";
		MessageBoxW(nullptr, (L"An error occurred: " + UTF8ToWString(e.what())).c_str(), L"Pictus Error", MB_OK);
		//throw;	// Good for debugging
	}

	Win::Control::DestructControls();

	return EXIT_SUCCESS;
}
<commit_msg>Use UTF8 for Boost.Filesystem<commit_after>#include "main.h"
#include "viewer.h"
#include "lang_val.h"
#include "registry.h"
#include "config.h"
#include "illa/codecmgr.h"
#include "orz/intl.h"
#include "control.h"
#include "w32_assure_folder.h"
#include "orz/logger.h"
#include <boost/locale.hpp>
#include <boost/filesystem.hpp>

int start_app(const std::string& params) {
	if (params == "--cleanup") {
		// If the user refused to uninstall the previous version when upgrading, the uninstaller will likely call pictus.exe with --cleanup
		// as parameter. Let's not throw up a blank Pictus windows in that situation.
		// This applies when 1.1.4.0 or older was installed.
		return EXIT_SUCCESS;
	}

	std::locale::global(boost::locale::generator().generate(""));
	boost::filesystem::path::imbue(std::locale());

	Img::CodecFactoryStore cfs;
	cfs.AddBuiltinCodecs();

	try {
		auto cfg = Reg::Load(App::cg_SettingsLocation);

		// TODO: Control logging by some other mechanism, such as an .ini setting
		Log.SetOutput(assure_folder(App::cg_RunLogLocation));

		Intl::LanguageTable(c_lang_strings);
		Intl::CurrentLanguage(cfg.View.Language);

		App::Viewer viewer(&cfs, cfg, params.c_str());

		// Attempt to display viewer
		if (viewer.Create(0)) {
			viewer.Show(true);
		}

		viewer.StartApplication();
	}
	catch(Err::DuplicateInstance&) {
		// This is not something out of the ordinary.
	}
	catch(Err::Exception& e) {
		Log << "Exception caught:\n" << e.what() << "\n";
		MessageBoxW(nullptr, (L"An error occurred: " + UTF8ToWString(e.what())).c_str(), L"Pictus Error", MB_OK);
		//throw;	// Good for debugging
	}

	Win::Control::DestructControls();

	return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#include "gpcheckcloud.h"

bool hasHeader;

char eolString[EOL_CHARS_MAX_LEN + 1] = "";  // meaningless for gpcheckcloud

string s3extErrorMessage;

volatile bool QueryCancelPending = false;

// As we can't catch 'IsAbortInProgress()' in UT, so here consider QueryCancelPending only
bool S3QueryIsAbortInProgress(void) {
    return QueryCancelPending;
}

void MaskThreadSignals() {
}

void *S3Alloc(size_t size) {
    return malloc(size);
}

void S3Free(void *p) {
    free(p);
}

static void handleAbortSignal(int signum) {
    fprintf(stderr, "Interrupted by user (%s), exiting...\n\n", strsignal(signum));
    QueryCancelPending = true;
}

void registerSignalHandler() {
    signal(SIGHUP, handleAbortSignal);
    signal(SIGABRT, handleAbortSignal);
    signal(SIGTERM, handleAbortSignal);
    signal(SIGINT, handleAbortSignal);
    signal(SIGTSTP, handleAbortSignal);
}

void printUsage(FILE *stream) {
    fprintf(stream,
            "Usage: gpcheckcloud -c \"s3://endpoint/bucket/prefix "
            "config=path_to_config_file [region=region_name]\", to check the configuration.\n"
            "       gpcheckcloud -d \"s3://endpoint/bucket/prefix "
            "config=path_to_config_file [region=region_name]\", to download and output to stdout.\n"
            "       gpcheckcloud -u \"/path/to/file\" \"s3://endpoint/bucket/prefix "
            "config=path_to_config_file [region=region_name]\", to upload a file.\n"
            "       gpcheckcloud -t, to show the config template.\n"
            "       gpcheckcloud -h, to show this help.\n");
}

// parse the arguments into char-string value pairs
map<char, string> parseCommandLineArgs(int argc, char *argv[]) {
    int opt = 0;
    map<char, string> optionPairs;

    while ((opt = getopt(argc, argv, "c:d:u:ht")) != -1) {
        switch (opt) {
            case 'c':
            case 'd':
            case 'h':
            case 't':
                if (optarg == NULL) {
                    optionPairs[opt] = "";
                } else if (optarg[0] == '-') {
                    fprintf(stderr, "Failed. Invalid argument for -%c: '%s'.\n\n", opt, optarg);
                    printUsage(stderr);
                    exit(EXIT_FAILURE);
                } else {
                    optionPairs[opt] = optarg;
                }

                break;
            case 'u':
                if (optarg == NULL) {
                    optionPairs[opt] = "";
                } else if (optind + 1 == argc) {      // has two option values
                    optionPairs['f'] = optarg;        // value of option file
                    optionPairs['u'] = argv[optind];  // value of option url
                } else {
                    fprintf(stderr, "Failed. Invalid arguments for -u, please check.\n\n");
                    printUsage(stderr);
                    exit(EXIT_FAILURE);
                }
                break;

            default:  // '?'
                printUsage(stderr);
                exit(EXIT_FAILURE);
        }
    }

    return optionPairs;
}

// check if command line arguments are valid
void validateCommandLineArgs(map<char, string> &optionPairs) {
    uint64_t count = optionPairs.count('f') + optionPairs.count('u');

    if ((count == 2) && (optionPairs.size() == 2)) {
        return;
    } else if (count == 1) {
        fprintf(stderr, "Failed. Option \'-u\' must work with \'-f\'.\n\n");
        printUsage(stderr);
        exit(EXIT_FAILURE);
    }

    if (optionPairs.size() > 1) {
        stringstream ss;

        ss << "Failed. Can't set options ";

        // concatenate all option names
        // e.g. if we have -c and -d, insert "-c, -d" into the stream.
        for (map<char, string>::iterator i = optionPairs.begin(); i != optionPairs.end(); i++) {
            ss << "'-" << i->first << "' ";
        }

        ss << "at the same time.";

        // example message: "Failed. Can't set options '-c' '-d' at the same time."
        fprintf(stderr, "%s\n\n", ss.str().c_str());
        printUsage(stderr);
        exit(EXIT_FAILURE);
    }
}

void printTemplate() {
    printf(
        "[default]\n"
        "secret = \"aws secret\"\n"
        "accessid = \"aws access id\"\n"
        "threadnum = 4\n"
        "chunksize = 67108864\n"
        "low_speed_limit = 10240\n"
        "low_speed_time = 60\n"
        "encryption = true\n"
        "autocompress = true\n"
        "proxy = \"\"\n");
}

void printBucketContents(const ListBucketResult &result) {
    char urlbuf[256];
    vector<BucketContent>::const_iterator i;

    for (i = result.contents.begin(); i != result.contents.end(); i++) {
        snprintf(urlbuf, 256, "%s", i->getName().c_str());
        printf("File: %s, Size: %" PRIu64 "\n", urlbuf, i->getSize());
    }
}

bool checkConfig(const char *urlWithOptions) {
    if (!urlWithOptions) {
        return false;
    }

    GPReader *reader = reader_init(urlWithOptions);
    if (!reader) {
        return false;
    }

    ListBucketResult result = reader->getKeyList();

    if (result.contents.empty()) {
        fprintf(stderr,
                "\nYour configuration works well, however there is no file matching your "
                "prefix.\n");
    } else {
        printBucketContents(result);
        fprintf(stderr, "\nYour configuration works well.\n");
    }

    reader_cleanup(&reader);

    return true;
}

bool downloadS3(const char *urlWithOptions) {
    if (!urlWithOptions) {
        return false;
    }

    int data_len = BUF_SIZE;
    char data_buf[BUF_SIZE];
    bool ret = true;

    thread_setup();

    GPReader *reader = reader_init(urlWithOptions);
    if (!reader) {
        return false;
    }

    do {
        data_len = BUF_SIZE;

        if (!reader_transfer_data(reader, data_buf, data_len)) {
            fprintf(stderr, "Failed to read data from Amazon S3\n");
            ret = false;
            break;
        }

        fwrite(data_buf, (size_t)data_len, 1, stdout);
    } while (data_len && !S3QueryIsAbortInProgress());

    reader_cleanup(&reader);

    thread_cleanup();

    return ret;
}

bool uploadS3(const char *urlWithOptions, const char *fileToUpload) {
    if (!urlWithOptions) {
        return false;
    }

    size_t data_len = BUF_SIZE;
    char data_buf[BUF_SIZE];
    size_t read_len = 0;
    bool ret = true;

    thread_setup();

    GPWriter *writer = writer_init(urlWithOptions);
    if (!writer) {
        return false;
    }

    FILE *fd = fopen(fileToUpload, "r");
    if (fd == NULL) {
        fprintf(stderr, "File does not exist\n");
        ret = false;
    } else {
        do {
            read_len = fread(data_buf, 1, data_len, fd);

            if (read_len == 0) {
                break;
            }

            if (!writer_transfer_data(writer, data_buf, (int)read_len)) {
                fprintf(stderr, "Failed to write data to Amazon S3\n");
                ret = false;
                break;
            }
        } while (read_len == data_len && !S3QueryIsAbortInProgress());

        if (ferror(fd)) {
            ret = false;
        }

        fclose(fd);
    }

    writer_cleanup(&writer);

    thread_cleanup();

    return ret;
}

int main(int argc, char *argv[]) {
    bool ret = true;

    s3ext_loglevel = EXT_ERROR;
    s3ext_logtype = STDERR_LOG;

    if (argc == 1) {
        printUsage(stderr);
        exit(EXIT_FAILURE);
    }

    /* Prepare to receive interrupts */
    registerSignalHandler();

    map<char, string> optionPairs = parseCommandLineArgs(argc, argv);

    validateCommandLineArgs(optionPairs);

    if (!optionPairs.empty()) {
        const char *arg = optionPairs.begin()->second.c_str();

        switch (optionPairs.begin()->first) {
            case 'c':
                ret = checkConfig(arg);
                break;
            case 'd':
                ret = downloadS3(arg);
                break;
            case 'u':
            case 'f':
                ret = uploadS3(optionPairs['u'].c_str(), optionPairs['f'].c_str());
                break;
            case 'h':
                printUsage(stdout);
                break;
            case 't':
                printTemplate();
                break;
            default:
                printUsage(stderr);
                exit(EXIT_FAILURE);
        }
    }

    // Abort should not print the failed info
    if (ret || S3QueryIsAbortInProgress()) {
        exit(EXIT_SUCCESS);
    } else {
        fprintf(stderr, "Failed. Please check the arguments and configuration file.\n\n");
        printUsage(stderr);
        exit(EXIT_FAILURE);
    }
}
<commit_msg>Mark local functions as static where appropriate<commit_after>#include "gpcheckcloud.h"

bool hasHeader;

char eolString[EOL_CHARS_MAX_LEN + 1] = "";  // meaningless for gpcheckcloud

string s3extErrorMessage;

volatile bool QueryCancelPending = false;

static bool uploadS3(const char *urlWithOptions, const char *fileToUpload);
static bool downloadS3(const char *urlWithOptions);
static bool checkConfig(const char *urlWithOptions);
static void printBucketContents(const ListBucketResult &result);
static void printTemplate();
static void validateCommandLineArgs(map<char, string> &optionPairs);
static map<char, string> parseCommandLineArgs(int argc, char *argv[]);
static void registerSignalHandler();
static void printUsage(FILE *stream);

// As we can't catch 'IsAbortInProgress()' in UT, so here consider QueryCancelPending only
bool S3QueryIsAbortInProgress(void) {
    return QueryCancelPending;
}

void MaskThreadSignals() {
}

void *S3Alloc(size_t size) {
    return malloc(size);
}

void S3Free(void *p) {
    free(p);
}

static void handleAbortSignal(int signum) {
    fprintf(stderr, "Interrupted by user (%s), exiting...\n\n", strsignal(signum));
    QueryCancelPending = true;
}

static void registerSignalHandler() {
    signal(SIGHUP, handleAbortSignal);
    signal(SIGABRT, handleAbortSignal);
    signal(SIGTERM, handleAbortSignal);
    signal(SIGINT, handleAbortSignal);
    signal(SIGTSTP, handleAbortSignal);
}

static void printUsage(FILE *stream) {
    fprintf(stream,
            "Usage: gpcheckcloud -c \"s3://endpoint/bucket/prefix "
            "config=path_to_config_file [region=region_name]\", to check the configuration.\n"
            "       gpcheckcloud -d \"s3://endpoint/bucket/prefix "
            "config=path_to_config_file [region=region_name]\", to download and output to stdout.\n"
            "       gpcheckcloud -u \"/path/to/file\" \"s3://endpoint/bucket/prefix "
            "config=path_to_config_file [region=region_name]\", to upload a file.\n"
            "       gpcheckcloud -t, to show the config template.\n"
            "       gpcheckcloud -h, to show this help.\n");
}

// parse the arguments into char-string value pairs
static map<char, string> parseCommandLineArgs(int argc, char *argv[]) {
    int opt = 0;
    map<char, string> optionPairs;

    while ((opt = getopt(argc, argv, "c:d:u:ht")) != -1) {
        switch (opt) {
            case 'c':
            case 'd':
            case 'h':
            case 't':
                if (optarg == NULL) {
                    optionPairs[opt] = "";
                } else if (optarg[0] == '-') {
                    fprintf(stderr, "Failed. Invalid argument for -%c: '%s'.\n\n", opt, optarg);
                    printUsage(stderr);
                    exit(EXIT_FAILURE);
                } else {
                    optionPairs[opt] = optarg;
                }

                break;
            case 'u':
                if (optarg == NULL) {
                    optionPairs[opt] = "";
                } else if (optind + 1 == argc) {      // has two option values
                    optionPairs['f'] = optarg;        // value of option file
                    optionPairs['u'] = argv[optind];  // value of option url
                } else {
                    fprintf(stderr, "Failed. Invalid arguments for -u, please check.\n\n");
                    printUsage(stderr);
                    exit(EXIT_FAILURE);
                }
                break;

            default:  // '?'
                printUsage(stderr);
                exit(EXIT_FAILURE);
        }
    }

    return optionPairs;
}

// check if command line arguments are valid
static void validateCommandLineArgs(map<char, string> &optionPairs) {
    uint64_t count = optionPairs.count('f') + optionPairs.count('u');

    if ((count == 2) && (optionPairs.size() == 2)) {
        return;
    } else if (count == 1) {
        fprintf(stderr, "Failed. Option \'-u\' must work with \'-f\'.\n\n");
        printUsage(stderr);
        exit(EXIT_FAILURE);
    }

    if (optionPairs.size() > 1) {
        stringstream ss;

        ss << "Failed. Can't set options ";

        // concatenate all option names
        // e.g. if we have -c and -d, insert "-c, -d" into the stream.
        for (map<char, string>::iterator i = optionPairs.begin(); i != optionPairs.end(); i++) {
            ss << "'-" << i->first << "' ";
        }

        ss << "at the same time.";

        // example message: "Failed. Can't set options '-c' '-d' at the same time."
        fprintf(stderr, "%s\n\n", ss.str().c_str());
        printUsage(stderr);
        exit(EXIT_FAILURE);
    }
}

static void printTemplate() {
    printf(
        "[default]\n"
        "secret = \"aws secret\"\n"
        "accessid = \"aws access id\"\n"
        "threadnum = 4\n"
        "chunksize = 67108864\n"
        "low_speed_limit = 10240\n"
        "low_speed_time = 60\n"
        "encryption = true\n"
        "autocompress = true\n"
        "proxy = \"\"\n");
}

static void printBucketContents(const ListBucketResult &result) {
    char urlbuf[256];
    vector<BucketContent>::const_iterator i;

    for (i = result.contents.begin(); i != result.contents.end(); i++) {
        snprintf(urlbuf, 256, "%s", i->getName().c_str());
        printf("File: %s, Size: %" PRIu64 "\n", urlbuf, i->getSize());
    }
}

static bool checkConfig(const char *urlWithOptions) {
    if (!urlWithOptions) {
        return false;
    }

    GPReader *reader = reader_init(urlWithOptions);
    if (!reader) {
        return false;
    }

    ListBucketResult result = reader->getKeyList();

    if (result.contents.empty()) {
        fprintf(stderr,
                "\nYour configuration works well, however there is no file matching your "
                "prefix.\n");
    } else {
        printBucketContents(result);
        fprintf(stderr, "\nYour configuration works well.\n");
    }

    reader_cleanup(&reader);

    return true;
}

static bool downloadS3(const char *urlWithOptions) {
    if (!urlWithOptions) {
        return false;
    }

    int data_len = BUF_SIZE;
    char data_buf[BUF_SIZE];
    bool ret = true;

    thread_setup();

    GPReader *reader = reader_init(urlWithOptions);
    if (!reader) {
        return false;
    }

    do {
        data_len = BUF_SIZE;

        if (!reader_transfer_data(reader, data_buf, data_len)) {
            fprintf(stderr, "Failed to read data from Amazon S3\n");
            ret = false;
            break;
        }

        fwrite(data_buf, (size_t)data_len, 1, stdout);
    } while (data_len && !S3QueryIsAbortInProgress());

    reader_cleanup(&reader);

    thread_cleanup();

    return ret;
}

static bool uploadS3(const char *urlWithOptions, const char *fileToUpload) {
    if (!urlWithOptions) {
        return false;
    }

    size_t data_len = BUF_SIZE;
    char data_buf[BUF_SIZE];
    size_t read_len = 0;
    bool ret = true;

    thread_setup();

    GPWriter *writer = writer_init(urlWithOptions);
    if (!writer) {
        return false;
    }

    FILE *fd = fopen(fileToUpload, "r");
    if (fd == NULL) {
        fprintf(stderr, "File does not exist\n");
        ret = false;
    } else {
        do {
            read_len = fread(data_buf, 1, data_len, fd);

            if (read_len == 0) {
                break;
            }

            if (!writer_transfer_data(writer, data_buf, (int)read_len)) {
                fprintf(stderr, "Failed to write data to Amazon S3\n");
                ret = false;
                break;
            }
        } while (read_len == data_len && !S3QueryIsAbortInProgress());

        if (ferror(fd)) {
            ret = false;
        }

        fclose(fd);
    }

    writer_cleanup(&writer);

    thread_cleanup();

    return ret;
}

int main(int argc, char *argv[]) {
    bool ret = true;

    s3ext_loglevel = EXT_ERROR;
    s3ext_logtype = STDERR_LOG;

    if (argc == 1) {
        printUsage(stderr);
        exit(EXIT_FAILURE);
    }

    /* Prepare to receive interrupts */
    registerSignalHandler();

    map<char, string> optionPairs = parseCommandLineArgs(argc, argv);

    validateCommandLineArgs(optionPairs);

    if (!optionPairs.empty()) {
        const char *arg = optionPairs.begin()->second.c_str();

        switch (optionPairs.begin()->first) {
            case 'c':
                ret = checkConfig(arg);
                break;
            case 'd':
                ret = downloadS3(arg);
                break;
            case 'u':
            case 'f':
                ret = uploadS3(optionPairs['u'].c_str(), optionPairs['f'].c_str());
                break;
            case 'h':
                printUsage(stdout);
                break;
            case 't':
                printTemplate();
                break;
            default:
                printUsage(stderr);
                exit(EXIT_FAILURE);
        }
    }

    // Abort should not print the failed info
    if (ret || S3QueryIsAbortInProgress()) {
        exit(EXIT_SUCCESS);
    } else {
        fprintf(stderr, "Failed. Please check the arguments and configuration file.\n\n");
        printUsage(stderr);
        exit(EXIT_FAILURE);
    }
}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2014, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

#include <string>
#include <fstream>
#include <map>

#include <stdlib.h>
#include <unistd.h>
#include <proc/readproc.h>

#include <boost/algorithm/string/trim.hpp>

#include <osquery/core.h>
#include <osquery/tables.h>
#include <osquery/filesystem.h>

namespace osquery {
namespace tables {

#ifdef PROC_EDITCMDLCVT
/// EDITCMDLCVT is available in libprocps3-dev
#define PROC_SELECTS                                                 \
  PROC_FILLCOM | PROC_EDITCMDLCVT | PROC_FILLMEM | PROC_FILLSTATUS | \
      PROC_FILLSTAT
#else
#define PROC_SELECTS \
  PROC_FILLCOM | PROC_FILLMEM | PROC_FILLSTATUS | PROC_FILLSTAT
#endif

std::string getProcName(const proc_t* proc_info) {
  return std::string(proc_info->cmd);
}

std::string getProcAttr(const std::string& attr, const proc_t* proc_info) {
  return "/proc/" + std::to_string(proc_info->tid) + "/" + attr;
}

std::string readProcCMDLine(const proc_t* proc_info) {
  auto attr = getProcAttr("cmdline", proc_info);

  std::string result;
  std::ifstream fd(attr, std::ios::in | std::ios::binary);
  if (fd) {
    result = std::string(std::istreambuf_iterator<char>(fd),
                         std::istreambuf_iterator<char>());
    std::replace_if(
      result.begin(),
      result.end(),
      [](const char& c) { return c == 0; },
      ' ');
  }

  return result;
}

std::string readProcLink(const proc_t* proc_info) {
  // The exe is a symlink to the binary on-disk.
  auto attr = getProcAttr("exe", proc_info);
  long path_max = pathconf(attr.c_str(), _PC_PATH_MAX);
  auto link_path = (char*)malloc(path_max);
  memset(link_path, 0, path_max);

  std::string result;
  int bytes = readlink(attr.c_str(), link_path, path_max);
  if (bytes >= 0) {
    result = std::string(link_path);
  }

  free(link_path);
  return result;
}

void genProcessEnvironment(const proc_t* proc_info, QueryData& results) {
  auto attr = getProcAttr("environ", proc_info);

  std::ifstream fd(attr, std::ios::in | std::ios::binary);
  std::string buf;
  while (!(fd.fail() || fd.eof())) {
    std::getline(fd, buf, '\0');
    size_t idx = buf.find_first_of("=");

    Row r;
    r["pid"] = INTEGER(proc_info->tid);
    r["key"] = buf.substr(0, idx);
    r["value"] = buf.substr(idx + 1);
    results.push_back(r);
  }
}

void genProcessMap(const proc_t* proc_info, QueryData& results) {
  auto map = getProcAttr("maps", proc_info);

  std::ifstream fd(map, std::ios::in | std::ios::binary);
  std::string line;
  while (!(fd.fail() || fd.eof())) {
    std::getline(fd, line, '\n');
    auto fields = osquery::split(line, " ");

    Row r;
    r["pid"] = INTEGER(proc_info->tid);

    // If can't read address, not sure.
    if (fields.size() < 5) {
      continue;
    }

    if (fields[0].size() > 0) {
      auto addresses = osquery::split(fields[0], "-");
      r["start"] = "0x" + addresses[0];
      r["end"] = "0x" + addresses[1];
    }

    r["permissions"] = fields[1];
    r["offset"] = BIGINT(std::stoll(fields[2], nullptr, 16));
    r["device"] = fields[3];
    r["inode"] = fields[4];

    // Path name must be trimmed.
    if (fields.size() > 5) {
      boost::trim(fields[5]);
      r["path"] = fields[5];
    }

    // BSS with name in pathname.
    r["is_pseudo"] = (fields[4] == "0" && r["path"].size() > 0) ? "1" : "0";
    results.push_back(r);
  }
}

/**
 * @brief deallocate the space allocated by readproc if the passed rbuf was NULL
 *
 * @param p The rbuf to free
 */
void standardFreeproc(proc_t* p) {
  if (!p) { // in case p is NULL
    return;
  }

#ifdef PROC_EDITCMDLCVT
  freeproc(p);
  return;
#endif

  // ptrs are after strings to avoid copying memory when building them.
  // so free is called on the address of the address of strvec[0].
  if (p->cmdline) {
    free((void*)*p->cmdline);
  }
  if (p->environ) {
    free((void*)*p->environ);
  }
  free(p);
}

QueryData genProcesses(QueryContext& context) {
  QueryData results;

  proc_t* proc_info;
  PROCTAB* proc = openproc(PROC_SELECTS);

  // Populate proc struc for each process.
  while ((proc_info = readproc(proc, NULL))) {
    if (!context.constraints["pid"].matches<int>(proc_info->tid)) {
      // Optimize by not searching when a pid is a constraint.
      standard_freeproc(proc_info);
      continue;
    }

    Row r;
    r["pid"] = INTEGER(proc_info->tid);
    r["uid"] = BIGINT((unsigned int)proc_info->ruid);
    r["gid"] = BIGINT((unsigned int)proc_info->rgid);
    r["euid"] = BIGINT((unsigned int)proc_info->euid);
    r["egid"] = BIGINT((unsigned int)proc_info->egid);
    r["name"] = getProcName(proc_info);
    std::string cmdline = readProcCMDLine(proc_info);
    boost::algorithm::trim(cmdline);
    r["cmdline"] = cmdline;
    r["path"] = readProcLink(proc_info);
    r["on_disk"] = osquery::pathExists(r["path"]).toString();

    r["resident_size"] = INTEGER(proc_info->vm_rss);
    r["phys_footprint"] = INTEGER(proc_info->vm_size);
    r["user_time"] = INTEGER(proc_info->utime);
    r["system_time"] = INTEGER(proc_info->stime);
    r["start_time"] = INTEGER(proc_info->start_time);
    r["parent"] = INTEGER(proc_info->ppid);

    results.push_back(r);
    standardFreeproc(proc_info);
  }

  closeproc(proc);

  return results;
}

QueryData genProcessEnvs(QueryContext& context) {
  QueryData results;

  proc_t* proc_info;
  PROCTAB* proc = openproc(PROC_SELECTS);

  // Populate proc struc for each process.
  while ((proc_info = readproc(proc, NULL))) {
    genProcessEnvironment(proc_info, results);
    standardFreeproc(proc_info);
  }

  closeproc(proc);

  return results;
}

QueryData genProcessMemoryMap(QueryContext& context) {
  QueryData results;

  proc_t* proc_info;
  PROCTAB* proc = openproc(PROC_SELECTS);

  while ((proc_info = readproc(proc, NULL))) {
    genProcessMap(proc_info, results);
    standardFreeproc(proc_info);
  }

  closeproc(proc);

  return results;
}
}
}
<commit_msg>Fix symbol rename regression in processes<commit_after>/*
 *  Copyright (c) 2014, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

#include <string>
#include <fstream>
#include <map>

#include <stdlib.h>
#include <unistd.h>
#include <proc/readproc.h>

#include <boost/algorithm/string/trim.hpp>

#include <osquery/core.h>
#include <osquery/tables.h>
#include <osquery/filesystem.h>

namespace osquery {
namespace tables {

#ifdef PROC_EDITCMDLCVT
/// EDITCMDLCVT is available in libprocps3-dev
#define PROC_SELECTS                                                 \
  PROC_FILLCOM | PROC_EDITCMDLCVT | PROC_FILLMEM | PROC_FILLSTATUS | \
      PROC_FILLSTAT
#else
#define PROC_SELECTS \
  PROC_FILLCOM | PROC_FILLMEM | PROC_FILLSTATUS | PROC_FILLSTAT
#endif

std::string getProcName(const proc_t* proc_info) {
  return std::string(proc_info->cmd);
}

std::string getProcAttr(const std::string& attr, const proc_t* proc_info) {
  return "/proc/" + std::to_string(proc_info->tid) + "/" + attr;
}

std::string readProcCMDLine(const proc_t* proc_info) {
  auto attr = getProcAttr("cmdline", proc_info);

  std::string result;
  std::ifstream fd(attr, std::ios::in | std::ios::binary);
  if (fd) {
    result = std::string(std::istreambuf_iterator<char>(fd),
                         std::istreambuf_iterator<char>());
    std::replace_if(
      result.begin(),
      result.end(),
      [](const char& c) { return c == 0; },
      ' ');
  }

  return result;
}

std::string readProcLink(const proc_t* proc_info) {
  // The exe is a symlink to the binary on-disk.
  auto attr = getProcAttr("exe", proc_info);
  long path_max = pathconf(attr.c_str(), _PC_PATH_MAX);
  auto link_path = (char*)malloc(path_max);
  memset(link_path, 0, path_max);

  std::string result;
  int bytes = readlink(attr.c_str(), link_path, path_max);
  if (bytes >= 0) {
    result = std::string(link_path);
  }

  free(link_path);
  return result;
}

void genProcessEnvironment(const proc_t* proc_info, QueryData& results) {
  auto attr = getProcAttr("environ", proc_info);

  std::ifstream fd(attr, std::ios::in | std::ios::binary);
  std::string buf;
  while (!(fd.fail() || fd.eof())) {
    std::getline(fd, buf, '\0');
    size_t idx = buf.find_first_of("=");

    Row r;
    r["pid"] = INTEGER(proc_info->tid);
    r["key"] = buf.substr(0, idx);
    r["value"] = buf.substr(idx + 1);
    results.push_back(r);
  }
}

void genProcessMap(const proc_t* proc_info, QueryData& results) {
  auto map = getProcAttr("maps", proc_info);

  std::ifstream fd(map, std::ios::in | std::ios::binary);
  std::string line;
  while (!(fd.fail() || fd.eof())) {
    std::getline(fd, line, '\n');
    auto fields = osquery::split(line, " ");

    Row r;
    r["pid"] = INTEGER(proc_info->tid);

    // If can't read address, not sure.
    if (fields.size() < 5) {
      continue;
    }

    if (fields[0].size() > 0) {
      auto addresses = osquery::split(fields[0], "-");
      r["start"] = "0x" + addresses[0];
      r["end"] = "0x" + addresses[1];
    }

    r["permissions"] = fields[1];
    r["offset"] = BIGINT(std::stoll(fields[2], nullptr, 16));
    r["device"] = fields[3];
    r["inode"] = fields[4];

    // Path name must be trimmed.
    if (fields.size() > 5) {
      boost::trim(fields[5]);
      r["path"] = fields[5];
    }

    // BSS with name in pathname.
    r["is_pseudo"] = (fields[4] == "0" && r["path"].size() > 0) ? "1" : "0";
    results.push_back(r);
  }
}

/**
 * @brief deallocate the space allocated by readproc if the passed rbuf was NULL
 *
 * @param p The rbuf to free
 */
void standardFreeproc(proc_t* p) {
  if (!p) { // in case p is NULL
    return;
  }

#ifdef PROC_EDITCMDLCVT
  freeproc(p);
  return;
#endif

  // ptrs are after strings to avoid copying memory when building them.
  // so free is called on the address of the address of strvec[0].
  if (p->cmdline) {
    free((void*)*p->cmdline);
  }
  if (p->environ) {
    free((void*)*p->environ);
  }
  free(p);
}

QueryData genProcesses(QueryContext& context) {
  QueryData results;

  proc_t* proc_info;
  PROCTAB* proc = openproc(PROC_SELECTS);

  // Populate proc struc for each process.
  while ((proc_info = readproc(proc, NULL))) {
    if (!context.constraints["pid"].matches<int>(proc_info->tid)) {
      // Optimize by not searching when a pid is a constraint.
      standardFreeproc(proc_info);
      continue;
    }

    Row r;
    r["pid"] = INTEGER(proc_info->tid);
    r["uid"] = BIGINT((unsigned int)proc_info->ruid);
    r["gid"] = BIGINT((unsigned int)proc_info->rgid);
    r["euid"] = BIGINT((unsigned int)proc_info->euid);
    r["egid"] = BIGINT((unsigned int)proc_info->egid);
    r["name"] = getProcName(proc_info);
    std::string cmdline = readProcCMDLine(proc_info);
    boost::algorithm::trim(cmdline);
    r["cmdline"] = cmdline;
    r["path"] = readProcLink(proc_info);
    r["on_disk"] = osquery::pathExists(r["path"]).toString();

    r["resident_size"] = INTEGER(proc_info->vm_rss);
    r["phys_footprint"] = INTEGER(proc_info->vm_size);
    r["user_time"] = INTEGER(proc_info->utime);
    r["system_time"] = INTEGER(proc_info->stime);
    r["start_time"] = INTEGER(proc_info->start_time);
    r["parent"] = INTEGER(proc_info->ppid);

    results.push_back(r);
    standardFreeproc(proc_info);
  }

  closeproc(proc);

  return results;
}

QueryData genProcessEnvs(QueryContext& context) {
  QueryData results;

  proc_t* proc_info;
  PROCTAB* proc = openproc(PROC_SELECTS);

  // Populate proc struc for each process.
  while ((proc_info = readproc(proc, NULL))) {
    genProcessEnvironment(proc_info, results);
    standardFreeproc(proc_info);
  }

  closeproc(proc);

  return results;
}

QueryData genProcessMemoryMap(QueryContext& context) {
  QueryData results;

  proc_t* proc_info;
  PROCTAB* proc = openproc(PROC_SELECTS);

  while ((proc_info = readproc(proc, NULL))) {
    genProcessMap(proc_info, results);
    standardFreeproc(proc_info);
  }

  closeproc(proc);

  return results;
}
}
}
<|endoftext|>


<commit_before>#include <windows.h>
#include <math.h>
#include <string>
using namespace std;
bool isClick = false;
int click_mouse_x;
int click_mouse_y;
int mouse_x;
int mouse_y;
int paint_x;
int paint_y;
int state = 0;
int state2 = 0;
HINSTANCE g_hInstance;

// ݹ ν Լ  Ÿ
LRESULT CALLBACK WndProc( HWND hWnd, UINT iMessage,
	WPARAM wParam, LPARAM lParam );
void Render(HDC hdc);
bool PointInRect( RECT r, int x, int y );

int APIENTRY WinMain(HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR lpCmdLine,
	int nCmdShow)
{
	g_hInstance = hInstance;
	wchar_t className[32] = L"SimpleWindow";
	wchar_t windowName[32] = L"SimpleWindow";

	// Ŭ
	// ̷  ڴ
	WNDCLASS WndClass;
	WndClass.cbClsExtra = 0;			//쿡 ϴ  ޸𸮼( ׳ 0 ̴  Ű澲 )
	WndClass.cbWndExtra = 0;			//쿡 ϴ  ޸𸮼( ׳ 0 ̴  Ű澲 )
	WndClass.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);		//
	WndClass.hCursor = LoadCursor( NULL, IDC_ARROW );			// Ŀ
	WndClass.hIcon = LoadIcon( NULL, IDI_APPLICATION );		//ܸ
	WndClass.hInstance = hInstance;				//α׷νϽڵ
	WndClass.lpfnWndProc = (WNDPROC)WndProc;			// ν Լ
	WndClass.lpszMenuName = NULL;						//޴̸  NULL
	WndClass.lpszClassName = className;				// ۼϰ ִ  Ŭ ̸
	WndClass.style	 = CS_HREDRAW | CS_VREDRAW;	// ׸   (  ɶ ȭ鰻 CS_HREDRAW | CS_VREDRAW )

	// ۼ  Ŭ
	RegisterClass( &WndClass );

	//
	//  ڵ  g_hWnd  ޴´.
	HWND hWnd = CreateWindow(
		className,				//Ǵ  Ŭ̸
		windowName,				// ŸƲٿ µǴ ̸
		WS_OVERLAPPEDWINDOW,	// Ÿ WS_OVERLAPPEDWINDOW
		0,				//  ġ X
		0,				//  ġ Y
		800,				//  ũ ( ۾ ũⰡ ƴ )
		600,				//  ũ ( ۾ ũⰡ ƴ )
		GetDesktopWindow(),		//θ  ڵ ( α׷ ֻ  NULL Ǵ GetDesktopWindow() )
		NULL,					//޴ ID ( ڽ Ʈ ü ΰ Ʈ ID
		hInstance,				// 찡  α׷ νϽ ڵ
		NULL					//߰  NULL ( Ű )
		);

	//츦 Ȯ ۾ ũ
	RECT rcClient = { 0, 0, 800, 600};
	AdjustWindowRect( &rcClient, WS_OVERLAPPEDWINDOW, FALSE );	//rcClient ũ⸦ ۾    ũ⸦ rcClient  ԵǾ ´.

	// ũ  ġ ٲپش.
	SetWindowPos( hWnd, NULL, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
		SWP_NOZORDER | SWP_NOMOVE );

	// 츦 ȭ鿡 .
	ShowWindow( hWnd, nCmdShow );

	//޽ ü
	MSG msg;
	ZeroMemory( &msg, sizeof(MSG) );

	while (msg.message != WM_QUIT)
	{
		//PeekMessage  ޽ ť ޽  α׷ ߱ ʰ  ȴ.
		//̶ ޽ť ޽  false  ϵǰ ޽  true  ̵ȴ.
		if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
		{
			TranslateMessage( &msg ); // Ű  ڸ Ͽ WM_CHAR ޽ ߻Ų.
			DispatchMessage( &msg );  //޾ƿ ޽   ν Լ Ų.
		}
	}

	return 0;
}

//
//  ν Լ ( ޽ ť ޾ƿ ޽ óѴ )
//
LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	PAINTSTRUCT ps;
	HDC hdc;

	switch (msg)
	{
	case WM_MOUSEWHEEL:
		break;

	case WM_PAINT: // ȭ ŵ  ȣȴ.
		{
			hdc = BeginPaint(hWnd, &ps);

			string str;
			TextOutA(hdc, 100, 100, str.c_str(), str.length());

			Rectangle(hdc, 100, 30, 150, 60);
			TextOutA(hdc, 100, 30, "Pen", 3);

			Rectangle(hdc, 200, 30, 250, 60);
			TextOutA(hdc, 200, 30, "Paint", 5);

			COLORREF rgb = GetPixel(hdc, 100, 100);

			if (state2 == 0)
			{
				static int sx = paint_x;
				static int sy = paint_y;
				MoveToEx(hdc, sx, sy, NULL);
				LineTo(hdc, paint_x, paint_y);
				sx = paint_x;
				sy = paint_y;
			}

			EndPaint(hWnd, &ps);
		}
		break;

//	case WM_ERASEBKGND:
//		return 0;

	case WM_LBUTTONDOWN:
		{
			POINT pos;
			pos.x = LOWORD(lParam);
			pos.y = HIWORD(lParam);

			RECT r1 = {100, 30, 150, 60};
			RECT r2 = {200, 30, 250, 60};

			if (PtInRect(&r1,pos))
			{
				state2 = 0;
			}

			if (PtInRect(&r2,pos))
			{
				state2 = 1;
			}

			isClick = true;
			if (state == 0)
			{
				click_mouse_x = LOWORD(lParam);
				click_mouse_y = HIWORD(lParam);
			}
			else if (state == 1)
			{
				mouse_x = LOWORD(lParam);
				mouse_y = HIWORD(lParam);
			}
			++state;
		}
		break;
	case WM_LBUTTONUP:
		{
			isClick = false;
		}
		break;
	case WM_MOUSEMOVE:
		{
			paint_x = LOWORD(lParam);
			paint_y = HIWORD(lParam);
			::InvalidateRect(hWnd, NULL, FALSE);
		}
		break;

	case WM_KEYDOWN:
		switch (wParam)
		{
		case VK_LEFT:
			break;
		case 'A':
			break;
		}
		break;

	case WM_DESTROY: //찡 ıȴٸ..
		PostQuitMessage(0);	//α׷  û ( ޽   ȴ )
		break;
	}

	return DefWindowProc( hWnd, msg, wParam, lParam ); // ⺻ ޼ ó Ѵ.
}

void Render(HDC hdc)
{
	const int w = 30;
	for (int x=0; x < 10; ++x)
	{
		for (int y=0; y < 10; ++y)
		{
			const int left = x*w;
			const int top = y*w;
			const RECT r = {left, top, left+w, top+w};

			Rectangle(hdc, r.left, r.top, r.right, r.bottom);
		}
	}

}

bool PointInRect( RECT r, int x, int y )
{
	return ((r.left < x) &&
		(r.right > x) &&
		(r.top < y) &&
		(r.bottom > y));
}
<commit_msg>update simple<commit_after>#include <windows.h>
#include <math.h>
#include <string>
#include <vector>
using namespace std;
bool isClick = false;
int click_mouse_x;
int click_mouse_y;
int mouse_x;
int mouse_y;
int paint_x;
int paint_y;
int fill_x;
int fill_y;
int state = 0;
int state2 = 0;
HINSTANCE g_hInstance;
bool fillPaint = false;

// ݹ ν Լ  Ÿ
LRESULT CALLBACK WndProc( HWND hWnd, UINT iMessage,
	WPARAM wParam, LPARAM lParam );
void Render(HDC hdc);
bool PointInRect( RECT r, int x, int y );

int APIENTRY WinMain(HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR lpCmdLine,
	int nCmdShow)
{
	g_hInstance = hInstance;
	wchar_t className[32] = L"SimpleWindow";
	wchar_t windowName[32] = L"SimpleWindow";

	// Ŭ
	// ̷  ڴ
	WNDCLASS WndClass;
	WndClass.cbClsExtra = 0;			//쿡 ϴ  ޸𸮼( ׳ 0 ̴  Ű澲 )
	WndClass.cbWndExtra = 0;			//쿡 ϴ  ޸𸮼( ׳ 0 ̴  Ű澲 )
	WndClass.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);		//
	WndClass.hCursor = LoadCursor( NULL, IDC_ARROW );			// Ŀ
	WndClass.hIcon = LoadIcon( NULL, IDI_APPLICATION );		//ܸ
	WndClass.hInstance = hInstance;				//α׷νϽڵ
	WndClass.lpfnWndProc = (WNDPROC)WndProc;			// ν Լ
	WndClass.lpszMenuName = NULL;						//޴̸  NULL
	WndClass.lpszClassName = className;				// ۼϰ ִ  Ŭ ̸
	WndClass.style	 = CS_HREDRAW | CS_VREDRAW;	// ׸   (  ɶ ȭ鰻 CS_HREDRAW | CS_VREDRAW )

	// ۼ  Ŭ
	RegisterClass( &WndClass );

	//
	//  ڵ  g_hWnd  ޴´.
	HWND hWnd = CreateWindow(
		className,				//Ǵ  Ŭ̸
		windowName,				// ŸƲٿ µǴ ̸
		WS_OVERLAPPEDWINDOW,	// Ÿ WS_OVERLAPPEDWINDOW
		0,				//  ġ X
		0,				//  ġ Y
		800,				//  ũ ( ۾ ũⰡ ƴ )
		600,				//  ũ ( ۾ ũⰡ ƴ )
		GetDesktopWindow(),		//θ  ڵ ( α׷ ֻ  NULL Ǵ GetDesktopWindow() )
		NULL,					//޴ ID ( ڽ Ʈ ü ΰ Ʈ ID
		hInstance,				// 찡  α׷ νϽ ڵ
		NULL					//߰  NULL ( Ű )
		);

	//츦 Ȯ ۾ ũ
	RECT rcClient = { 0, 0, 800, 600};
	AdjustWindowRect( &rcClient, WS_OVERLAPPEDWINDOW, FALSE );	//rcClient ũ⸦ ۾    ũ⸦ rcClient  ԵǾ ´.

	// ũ  ġ ٲپش.
	SetWindowPos( hWnd, NULL, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
		SWP_NOZORDER | SWP_NOMOVE );

	// 츦 ȭ鿡 .
	ShowWindow( hWnd, nCmdShow );

	//޽ ü
	MSG msg;
	ZeroMemory( &msg, sizeof(MSG) );

	while (msg.message != WM_QUIT)
	{
		//PeekMessage  ޽ ť ޽  α׷ ߱ ʰ  ȴ.
		//̶ ޽ť ޽  false  ϵǰ ޽  true  ̵ȴ.
		if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
		{
			TranslateMessage( &msg ); // Ű  ڸ Ͽ WM_CHAR ޽ ߻Ų.
			DispatchMessage( &msg );  //޾ƿ ޽   ν Լ Ų.
		}
	}

	return 0;
}

//
//  ν Լ ( ޽ ť ޾ƿ ޽ óѴ )
//
LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	PAINTSTRUCT ps;
	HDC hdc;

	switch (msg)
	{
	case WM_MOUSEWHEEL:
		break;

	case WM_PAINT: // ȭ ŵ  ȣȴ.
		{
			hdc = BeginPaint(hWnd, &ps);

			string str;
			TextOutA(hdc, 100, 100, str.c_str(), str.length());

			Rectangle(hdc, 100, 30, 150, 60);
			TextOutA(hdc, 100, 30, "Pen", 3);

			Rectangle(hdc, 200, 30, 250, 60);
			TextOutA(hdc, 200, 30, "Paint", 5);

			if (state2 == 0)
			{
				static int sx = paint_x;
				static int sy = paint_y;
				MoveToEx(hdc, sx, sy, NULL);
				LineTo(hdc, paint_x, paint_y);
				sx = paint_x;
				sy = paint_y;
			}

			if (fillPaint == true)
			{
				fillPaint = false;
				std::vector<POINT> array(1000000);
				array[ 0].x = fill_x;
				array[ 0].y = fill_y;
				int cnt = 1;
				COLORREF orig_color = GetPixel(hdc, fill_x, fill_y);

				while (cnt > 0)
				{
					POINT pos = array[ cnt-1];
					--cnt;
					COLORREF color = GetPixel(hdc, pos.x, pos.y);
					if (color == orig_color)
					{
						SetPixel(hdc, pos.x, pos.y, RGB(255,0,255));

						POINT env[4] = {{-1,0}, {0,-1}, {1,0}, {0,1}};
						for (int i=0; i < 4; ++i)
						{
							int x = pos.x + env[ i].x;
							int y = pos.y + env[ i].y;
							if ((x < 0) || (x > 1000))
								continue;
							if ((y < 0) || (y > 1000))
								continue;
							if (GetPixel(hdc, x, y) != orig_color)
								continue;

							array[ cnt].x = x;
							array[ cnt].y = y;
							++cnt;

							if (cnt >= 1000000)
							{
								cnt = 0;
								break;
							}

						}
					}
				}
			}

			EndPaint(hWnd, &ps);
		}
		break;

//	case WM_ERASEBKGND:
//		return 0;

	case WM_LBUTTONDOWN:
		{
			POINT pos;
			pos.x = LOWORD(lParam);
			pos.y = HIWORD(lParam);

			RECT r1 = {100, 30, 150, 60};
			RECT r2 = {200, 30, 250, 60};

			if (PtInRect(&r1,pos))
			{
				state2 = 0;
			}
			else if (PtInRect(&r2,pos))
			{
				state2 = 1;
			}
			else
			{
				if (state2 == 1)
				{
					fill_x = pos.x;
					fill_y = pos.y;
					fillPaint = true;
				}
			}

			isClick = true;
			if (state == 0)
			{
				click_mouse_x = LOWORD(lParam);
				click_mouse_y = HIWORD(lParam);
			}
			else if (state == 1)
			{
				mouse_x = LOWORD(lParam);
				mouse_y = HIWORD(lParam);
			}
			++state;
		}
		break;
	case WM_LBUTTONUP:
		{
			isClick = false;
		}
		break;
	case WM_MOUSEMOVE:
		{
			paint_x = LOWORD(lParam);
			paint_y = HIWORD(lParam);
			::InvalidateRect(hWnd, NULL, FALSE);
		}
		break;

	case WM_KEYDOWN:
		switch (wParam)
		{
		case VK_LEFT:
			break;
		case 'A':
			break;
		}
		break;

	case WM_DESTROY: //찡 ıȴٸ..
		PostQuitMessage(0);	//α׷  û ( ޽   ȴ )
		break;
	}

	return DefWindowProc( hWnd, msg, wParam, lParam ); // ⺻ ޼ ó Ѵ.
}

void Render(HDC hdc)
{
	const int w = 30;
	for (int x=0; x < 10; ++x)
	{
		for (int y=0; y < 10; ++y)
		{
			const int left = x*w;
			const int top = y*w;
			const RECT r = {left, top, left+w, top+w};

			Rectangle(hdc, r.left, r.top, r.right, r.bottom);
		}
	}

}

bool PointInRect( RECT r, int x, int y )
{
	return ((r.left < x) &&
		(r.right > x) &&
		(r.top < y) &&
		(r.bottom > y));
}
<|endoftext|>


<commit_before>#ifndef ITER_IMAP_H_
#define ITER_IMAP_H_

#include "zip.hpp"

#include <utility>
#include <type_traits>

namespace iter {

    namespace detail {

    template <std::size_t Index, typename Functor, typename Tup>
    struct Expander {
        template <typename... Ts>
        static auto call(Functor&& f, Tup&& tup, Ts&&... args)
            -> decltype(Expander<Index-1, Functor, Tup>::call(
                    std::forward<Functor>(f),
                    std::forward<Tup>(tup),
                    std::get<Index-1>(tup),
                    std::forward<Ts>(args)...))
        {
            // recurse
            return Expander<Index-1, Functor, Tup>::call(
                    std::forward<Functor>(f),
                    std::forward<Tup>(tup),
                    std::get<Index-1>(tup), // pull out one element
                    std::forward<Ts>(args)...); // everything already expanded
        }
    };

    template <typename Functor, typename Tup>
    struct Expander<0, Functor, Tup> {
        template <typename... Ts>
        static auto call(Functor&& f, Tup&&, Ts&&... args)
            -> decltype(f(std::forward<Ts>(args)...))
        {
            static_assert(
                std::tuple_size<
                    typename std::remove_reference<Tup>::type>::value
                    == sizeof...(Ts),
                "tuple has not been fully expanded");
            return f(std::forward<Ts>(args)...); // the actual call
        }
    };

    template <typename Functor, typename Tup>
    auto call_with_tuple(Functor&& f, Tup&& tup)
        -> decltype(Expander<std::tuple_size<
                    typename std::remove_reference<Tup>::type>::value,
                    Functor, Tup>::call(
                        std::forward<Functor>(f),
                        std::forward<Tup>(tup)))
    {
        return Expander<std::tuple_size<
            typename std::remove_reference<Tup>::type>::value,
            Functor, Tup>::call(
                std::forward<Functor>(f),
                std::forward<Tup>(tup));
    }

    } // end detail

    //Forward declarations of IMap and imap
    template <typename MapFunc, typename... Containers>
    class IMap;

    template <typename MapFunc, typename... Containers>
    IMap<MapFunc, Containers...> imap(MapFunc, Containers&&...);

    template <typename MapFunc, typename... Containers>
    class IMap {
        // The imap function is the only thing allowed to create a IMap
        friend IMap imap<MapFunc, Containers...>(MapFunc, Containers&& ...);

        using ZippedType = decltype(zip(std::declval<Containers>()...));
        using ZippedIterType = iterator_type<ZippedType>;
        private:
            MapFunc map_func;
            ZippedType zipped;

            using IMapIterDeref = decltype(detail::call_with_tuple(
                        map_func, *std::begin(zipped)));

            // Value constructor for use only in the imap function
            IMap(MapFunc map_func, Containers&& ... containers) :
                map_func(map_func),
                zipped(zip(std::forward<Containers>(containers)...))
            { }

        public:
            class Iterator
                : public std::iterator<std::input_iterator_tag,
                    typename std::remove_reference<IMapIterDeref>::type >
            {
                private:
                    MapFunc map_func;
                    ZippedIterType zipiter;

                public:
                    Iterator(MapFunc map_func, ZippedIterType zipiter) :
                        map_func(map_func),
                        zipiter(zipiter)
                    { }

                    IMapIterDeref operator*() {
                        return detail::call_with_tuple(
                                this->map_func, *(this->zipiter));
                    }

                    Iterator& operator++() {
                        ++this->zipiter;
                        return *this;
                    }

                    Iterator operator++(int) {
                        auto ret = *this;
                        ++*this;
                        return ret;
                    }

                    bool operator!=(const Iterator& other) const {
                        return this->zipiter != other.zipiter;
                    }

                    bool operator==(const Iterator& other) const {
                        return !(*this != other);
                    }
            };

            Iterator begin() {
                return {this->map_func, this->zipped.begin()};
            }

            Iterator end() {
                return {this->map_func, this->zipped.end()};
            }

    };

    // Helper function to instantiate a IMap
    template <typename MapFunc, typename... Containers>
    IMap<MapFunc, Containers...> imap(
            MapFunc map_func, Containers&& ... containers) {
        return {map_func, std::forward<Containers>(containers)...};
    }

}

#endif // #ifndef ITER_IMAP_H_
<commit_msg>moves rather than copies iterators<commit_after>#ifndef ITER_IMAP_H_
#define ITER_IMAP_H_

#include "zip.hpp"

#include <utility>
#include <type_traits>

namespace iter {

    namespace detail {

    template <std::size_t Index, typename Functor, typename Tup>
    struct Expander {
        template <typename... Ts>
        static auto call(Functor&& f, Tup&& tup, Ts&&... args)
            -> decltype(Expander<Index-1, Functor, Tup>::call(
                    std::forward<Functor>(f),
                    std::forward<Tup>(tup),
                    std::get<Index-1>(tup),
                    std::forward<Ts>(args)...))
        {
            // recurse
            return Expander<Index-1, Functor, Tup>::call(
                    std::forward<Functor>(f),
                    std::forward<Tup>(tup),
                    std::get<Index-1>(tup), // pull out one element
                    std::forward<Ts>(args)...); // everything already expanded
        }
    };

    template <typename Functor, typename Tup>
    struct Expander<0, Functor, Tup> {
        template <typename... Ts>
        static auto call(Functor&& f, Tup&&, Ts&&... args)
            -> decltype(f(std::forward<Ts>(args)...))
        {
            static_assert(
                std::tuple_size<
                    typename std::remove_reference<Tup>::type>::value
                    == sizeof...(Ts),
                "tuple has not been fully expanded");
            return f(std::forward<Ts>(args)...); // the actual call
        }
    };

    template <typename Functor, typename Tup>
    auto call_with_tuple(Functor&& f, Tup&& tup)
        -> decltype(Expander<std::tuple_size<
                    typename std::remove_reference<Tup>::type>::value,
                    Functor, Tup>::call(
                        std::forward<Functor>(f),
                        std::forward<Tup>(tup)))
    {
        return Expander<std::tuple_size<
            typename std::remove_reference<Tup>::type>::value,
            Functor, Tup>::call(
                std::forward<Functor>(f),
                std::forward<Tup>(tup));
    }

    } // end detail

    //Forward declarations of IMap and imap
    template <typename MapFunc, typename... Containers>
    class IMap;

    template <typename MapFunc, typename... Containers>
    IMap<MapFunc, Containers...> imap(MapFunc, Containers&&...);

    template <typename MapFunc, typename... Containers>
    class IMap {
        // The imap function is the only thing allowed to create a IMap
        friend IMap imap<MapFunc, Containers...>(MapFunc, Containers&& ...);

        using ZippedType = decltype(zip(std::declval<Containers>()...));
        using ZippedIterType = iterator_type<ZippedType>;
        private:
            MapFunc map_func;
            ZippedType zipped;

            using IMapIterDeref = decltype(detail::call_with_tuple(
                        map_func, *std::begin(zipped)));

            // Value constructor for use only in the imap function
            IMap(MapFunc map_func, Containers&& ... containers) :
                map_func(map_func),
                zipped(zip(std::forward<Containers>(containers)...))
            { }

        public:
            class Iterator
                : public std::iterator<std::input_iterator_tag,
                    typename std::remove_reference<IMapIterDeref>::type >
            {
                private:
                    MapFunc map_func;
                    ZippedIterType zipiter;

                public:
                    Iterator(MapFunc map_func, ZippedIterType&& in_zipiter) :
                        map_func(map_func),
                        zipiter(std::move(in_zipiter))
                    { }

                    IMapIterDeref operator*() {
                        return detail::call_with_tuple(
                                this->map_func, *(this->zipiter));
                    }

                    Iterator& operator++() {
                        ++this->zipiter;
                        return *this;
                    }

                    Iterator operator++(int) {
                        auto ret = *this;
                        ++*this;
                        return ret;
                    }

                    bool operator!=(const Iterator& other) const {
                        return this->zipiter != other.zipiter;
                    }

                    bool operator==(const Iterator& other) const {
                        return !(*this != other);
                    }
            };

            Iterator begin() {
                return {this->map_func, this->zipped.begin()};
            }

            Iterator end() {
                return {this->map_func, this->zipped.end()};
            }

    };

    // Helper function to instantiate a IMap
    template <typename MapFunc, typename... Containers>
    IMap<MapFunc, Containers...> imap(
            MapFunc map_func, Containers&& ... containers) {
        return {map_func, std::forward<Containers>(containers)...};
    }

}

#endif // #ifndef ITER_IMAP_H_
<|endoftext|>


<commit_before>#include "mfem.hpp"
#include <fstream>
#include <iostream>
#include <memory>

using namespace std;
using namespace mfem;

int exact_sol = 0;
int dim = 0;

void E_exact(const Vector &xvec, Vector &E)
{
   double x=xvec[0], y=xvec[1], z=xvec[2];
   constexpr double pi = M_PI;

   if (exact_sol == 0)
   {
      E[0] = sin(2*pi*x)*sin(4*pi*y);
      E[1] = sin(4*pi*x)*sin(2*pi*y);
   }
   else if (exact_sol == 1)
   {
      if (dim == 3)
      {
         E(0) = x * y * (1.0-y) * z * (1.0-z);
         E(1) = x * y * (1.0-x) * z * (1.0-z);
         E(2) = x * z * (1.0-x) * y * (1.0-y);
      }
      else
      {
         E(0) = y * (1.0-y);
         E(1) = x * (1.0-x);
      }
   }
   else if (exact_sol == 2)
   {
      E[0] = cos(2*pi*x)*cos(4*pi*y);
      E[1] = cos(4*pi*x)*cos(2*pi*y);
   }
   else if (exact_sol == 3)
   {
      constexpr double kappa = 2.0 * pi;

      if (dim == 3)
      {
         E(0) = sin(kappa * y);
         E(1) = sin(kappa * z);
         E(2) = sin(kappa * x);
      }
   }
   else
   {
      constexpr double kappa = 2.0 * pi;
      if (dim == 3)
      {
         E(0) = sin(kappa * y) * sin(kappa * z);
         E(1) = sin(kappa * x) * sin(kappa * z);
         E(2) = sin(kappa * x) * sin(kappa * y);
      }
      else
      {
         E(0) = sin(kappa * y);
         E(1) = sin(kappa * x);
         if (xvec.Size() == 3) { E(2) = 0.0; }
      }
   }
}

void f_exact(const Vector &xvec, Vector &f)
{
   double x=xvec[0], y=xvec[1], z=xvec[2];
   constexpr double pi = M_PI;
   constexpr double pi2 = M_PI*M_PI;

   if (exact_sol == 0)
   {
      f[0] = 8*pi2*cos(4*pi*x)*cos(2*pi*y) + (1 + 16*pi2)*sin(2*pi*x)*sin(4*pi*y);
      f[1] = 8*pi2*cos(2*pi*x)*cos(4*pi*y) + (1 + 16*pi2)*sin(4*pi*x)*sin(2*pi*y);
   }
   else if (exact_sol == 1)
   {
      if (dim == 3)
      {
         f(0) = x * y * (1.0-y) * z * (1.0-z);
         f(1) = x * y * (1.0-x) * z * (1.0-z);
         f(2) = x * z * (1.0-x) * y * (1.0-y);

         f(0) += y * (1.0-y) + z * (1.0-z);
         f(1) += x * (1.0-x) + z * (1.0-z);
         f(2) += x * (1.0-x) + y * (1.0-y);
      }
      else
      {
         f(0) = y * (1.0-y);
         f(1) = x * (1.0-x);

         f(0) += 2.0;
         f(1) += 2.0;
      }
   }
   else if (exact_sol == 2)
   {
      f[0] = 8*pi2*sin(4*pi*x)*sin(2*pi*y) + (1 + 16*pi2)*cos(2*pi*x)*cos(4*pi*y);
      f[1] = 8*pi2*sin(2*pi*x)*sin(4*pi*y) + (1 + 16*pi2)*cos(4*pi*x)*cos(2*pi*y);
   }
   else if (exact_sol == 3)
   {
      constexpr double kappa = 2.0 * pi;
      if (dim == 3)
      {
         f(0) = (1. + kappa * kappa) * sin(kappa * y);
         f(1) = (1. + kappa * kappa) * sin(kappa * z);
         f(2) = (1. + kappa * kappa) * sin(kappa * x);
      }
   }
   else
   {
      constexpr double kappa = 2.0 * pi;
      if (dim == 3)
      {
         f(0) = (1.0 + 2.0 * kappa * kappa) * sin(kappa * y) * sin(kappa * z);
         f(1) = (1.0 + 2.0 * kappa * kappa) * sin(kappa * x) * sin(kappa * z);
         f(2) = (1.0 + 2.0 * kappa * kappa) * sin(kappa * x) * sin(kappa * y);
      }
      else
      {
         f(0) = (1. + kappa * kappa) * sin(kappa * y);
         f(1) = (1. + kappa * kappa) * sin(kappa * x);
         if (xvec.Size() == 3) { f(2) = 0.0; }
      }
   }
}

int main(int argc, char *argv[])
{
   // 1. Parse command-line options.
   const char *mesh_file = "../data/star.mesh";
   int ref_levels = 0;
   int order = 3;
   const char *fe = "n";

   OptionsParser args(argc, argv);
   args.AddOption(&mesh_file, "-m", "--mesh", "Mesh file to use.");
   args.AddOption(&ref_levels, "-r", "--refine", "Uniform refinements.");
   args.AddOption(&order, "-o", "--order", "Polynomial degree.");
   args.AddOption(&exact_sol, "-p", "--problem", "Exact solution.");
   args.AddOption(&fe, "-fe", "--fe-type", "FE type. n for Hcurl, r for Hdiv");
   args.ParseCheck();

   bool ND;
   if (string(fe) == "n") { ND = true; }
   else if (string(fe) == "r") { ND = false; }
   else { MFEM_ABORT("Bad FE type. Must be 'n' or 'r'."); }

   Mesh mesh(mesh_file, 1, 1);
   dim = mesh.Dimension();
   for (int l = 0; l < ref_levels; l++) { mesh.UniformRefinement(); }

   int b1 = BasisType::GaussLobatto, b2 = BasisType::Integrated;
   unique_ptr<FiniteElementCollection> fec;
   if (ND) { fec.reset(new ND_FECollection(order, dim, b1, b2)); }
   else { fec.reset(new RT_FECollection(order-1, dim, b1, b2)); }

   FiniteElementSpace fes(&mesh, fec.get());
   Array<int> ess_dofs;
   fes.GetBoundaryTrueDofs(ess_dofs);

   BilinearForm a_ho(&fes);
   a_ho.AddDomainIntegrator(new VectorFEMassIntegrator);
   if (ND) { a_ho.AddDomainIntegrator(new CurlCurlIntegrator); }
   else { a_ho.AddDomainIntegrator(new DivDivIntegrator); }
   a_ho.SetAssemblyLevel(AssemblyLevel::PARTIAL);
   a_ho.Assemble();

   LinearForm b(&fes);
   VectorFunctionCoefficient f_coeff(dim, f_exact);
   b.AddDomainIntegrator(new VectorFEDomainLFIntegrator(f_coeff));
   b.Assemble();

   GridFunction x(&fes);
   VectorFunctionCoefficient exact_coeff(dim, E_exact);
   x.ProjectCoefficient(exact_coeff);

   Vector X, B;
   OperatorHandle A;
   a_ho.FormLinearSystem(ess_dofs, x, b, A, X, B);

   LORSolver<UMFPackSolver> lor_solver(a_ho, ess_dofs);

   CGSolver cg;
   cg.SetAbsTol(0.0);
   cg.SetRelTol(1e-12);
   cg.SetMaxIter(100);
   cg.SetPrintLevel(1);
   cg.SetOperator(*A);
   cg.SetPreconditioner(lor_solver);
   cg.Mult(B, X);
   a_ho.RecoverFEMSolution(X, b, x);

   double er = x.ComputeL2Error(exact_coeff);
   std::cout << "L^2 error: " << er << '\n';

   ParaViewDataCollection dc("LOR", &mesh);
   dc.SetPrefixPath("ParaView");
   dc.SetHighOrderOutput(true);
   dc.SetLevelsOfDetail(order);
   dc.RegisterField("u", &x);
   dc.SetCycle(0);
   dc.SetTime(0.0);
   dc.Save();

   return 0;
}
<commit_msg>Minor<commit_after>#include "mfem.hpp"
#include <fstream>
#include <iostream>
#include <memory>

using namespace std;
using namespace mfem;

int exact_sol = 0;
int dim = 0;

void E_exact(const Vector &xvec, Vector &E)
{
   double x=xvec[0], y=xvec[1], z=xvec[2];
   constexpr double pi = M_PI;

   if (exact_sol == 0)
   {
      E[0] = sin(2*pi*x)*sin(4*pi*y);
      E[1] = sin(4*pi*x)*sin(2*pi*y);
   }
   else if (exact_sol == 1)
   {
      if (dim == 3)
      {
         E(0) = x * y * (1.0-y) * z * (1.0-z);
         E(1) = x * y * (1.0-x) * z * (1.0-z);
         E(2) = x * z * (1.0-x) * y * (1.0-y);
      }
      else
      {
         E(0) = y * (1.0-y);
         E(1) = x * (1.0-x);
      }
   }
   else if (exact_sol == 2)
   {
      E[0] = cos(2*pi*x)*cos(4*pi*y);
      E[1] = cos(4*pi*x)*cos(2*pi*y);
   }
   else if (exact_sol == 3)
   {
      constexpr double kappa = 2.0 * pi;

      if (dim == 3)
      {
         E(0) = sin(kappa * y);
         E(1) = sin(kappa * z);
         E(2) = sin(kappa * x);
      }
   }
   else
   {
      constexpr double kappa = 2.0 * pi;
      if (dim == 3)
      {
         E(0) = sin(kappa * y) * sin(kappa * z);
         E(1) = sin(kappa * x) * sin(kappa * z);
         E(2) = sin(kappa * x) * sin(kappa * y);
      }
      else
      {
         E(0) = sin(kappa * y);
         E(1) = sin(kappa * x);
         if (xvec.Size() == 3) { E(2) = 0.0; }
      }
   }
}

void f_exact(const Vector &xvec, Vector &f)
{
   double x=xvec[0], y=xvec[1], z=xvec[2];
   constexpr double pi = M_PI;
   constexpr double pi2 = M_PI*M_PI;

   if (exact_sol == 0)
   {
      f[0] = 8*pi2*cos(4*pi*x)*cos(2*pi*y) + (1 + 16*pi2)*sin(2*pi*x)*sin(4*pi*y);
      f[1] = 8*pi2*cos(2*pi*x)*cos(4*pi*y) + (1 + 16*pi2)*sin(4*pi*x)*sin(2*pi*y);
   }
   else if (exact_sol == 1)
   {
      if (dim == 3)
      {
         f(0) = x * y * (1.0-y) * z * (1.0-z);
         f(1) = x * y * (1.0-x) * z * (1.0-z);
         f(2) = x * z * (1.0-x) * y * (1.0-y);

         f(0) += y * (1.0-y) + z * (1.0-z);
         f(1) += x * (1.0-x) + z * (1.0-z);
         f(2) += x * (1.0-x) + y * (1.0-y);
      }
      else
      {
         f(0) = y * (1.0-y);
         f(1) = x * (1.0-x);

         f(0) += 2.0;
         f(1) += 2.0;
      }
   }
   else if (exact_sol == 2)
   {
      f[0] = 8*pi2*sin(4*pi*x)*sin(2*pi*y) + (1 + 16*pi2)*cos(2*pi*x)*cos(4*pi*y);
      f[1] = 8*pi2*sin(2*pi*x)*sin(4*pi*y) + (1 + 16*pi2)*cos(4*pi*x)*cos(2*pi*y);
   }
   else if (exact_sol == 3)
   {
      constexpr double kappa = 2.0 * pi;
      if (dim == 3)
      {
         f(0) = (1. + kappa * kappa) * sin(kappa * y);
         f(1) = (1. + kappa * kappa) * sin(kappa * z);
         f(2) = (1. + kappa * kappa) * sin(kappa * x);
      }
   }
   else
   {
      constexpr double kappa = 2.0 * pi;
      if (dim == 3)
      {
         f(0) = (1.0 + 2.0 * kappa * kappa) * sin(kappa * y) * sin(kappa * z);
         f(1) = (1.0 + 2.0 * kappa * kappa) * sin(kappa * x) * sin(kappa * z);
         f(2) = (1.0 + 2.0 * kappa * kappa) * sin(kappa * x) * sin(kappa * y);
      }
      else
      {
         f(0) = (1. + kappa * kappa) * sin(kappa * y);
         f(1) = (1. + kappa * kappa) * sin(kappa * x);
         if (xvec.Size() == 3) { f(2) = 0.0; }
      }
   }
}

int main(int argc, char *argv[])
{
   // 1. Parse command-line options.
   const char *mesh_file = "../data/star.mesh";
   int ref_levels = 0;
   int order = 3;
   const char *fe = "n";

   OptionsParser args(argc, argv);
   args.AddOption(&mesh_file, "-m", "--mesh", "Mesh file to use.");
   args.AddOption(&ref_levels, "-r", "--refine", "Uniform refinements.");
   args.AddOption(&order, "-o", "--order", "Polynomial degree.");
   args.AddOption(&exact_sol, "-p", "--problem", "Exact solution.");
   args.AddOption(&fe, "-fe", "--fe-type", "FE type. n for Hcurl, r for Hdiv");
   args.ParseCheck();

   bool ND;
   if (string(fe) == "n") { ND = true; }
   else if (string(fe) == "r") { ND = false; }
   else { MFEM_ABORT("Bad FE type. Must be 'n' or 'r'."); }

   Mesh mesh(mesh_file, 1, 1);
   dim = mesh.Dimension();
   for (int l = 0; l < ref_levels; l++) { mesh.UniformRefinement(); }

   int b1 = BasisType::GaussLobatto, b2 = BasisType::Integrated;
   unique_ptr<FiniteElementCollection> fec;
   if (ND) { fec.reset(new ND_FECollection(order, dim, b1, b2)); }
   else { fec.reset(new RT_FECollection(order-1, dim, b1, b2)); }

   FiniteElementSpace fes(&mesh, fec.get());
   Array<int> ess_dofs;
   fes.GetBoundaryTrueDofs(ess_dofs);

   BilinearForm a(&fes);
   a.AddDomainIntegrator(new VectorFEMassIntegrator);
   if (ND) { a.AddDomainIntegrator(new CurlCurlIntegrator); }
   else { a.AddDomainIntegrator(new DivDivIntegrator); }
   a.SetAssemblyLevel(AssemblyLevel::PARTIAL);
   a.Assemble();

   LinearForm b(&fes);
   VectorFunctionCoefficient f_coeff(dim, f_exact);
   b.AddDomainIntegrator(new VectorFEDomainLFIntegrator(f_coeff));
   b.Assemble();

   GridFunction x(&fes);
   VectorFunctionCoefficient exact_coeff(dim, E_exact);
   x.ProjectCoefficient(exact_coeff);

   Vector X, B;
   OperatorHandle A;
   a.FormLinearSystem(ess_dofs, x, b, A, X, B);

   LORSolver<UMFPackSolver> lor_solver(a, ess_dofs);

   CGSolver cg;
   cg.SetAbsTol(0.0);
   cg.SetRelTol(1e-12);
   cg.SetMaxIter(100);
   cg.SetPrintLevel(1);
   cg.SetOperator(*A);
   cg.SetPreconditioner(lor_solver);
   cg.Mult(B, X);
   a.RecoverFEMSolution(X, b, x);

   double er = x.ComputeL2Error(exact_coeff);
   std::cout << "L^2 error: " << er << '\n';

   ParaViewDataCollection dc("LOR", &mesh);
   dc.SetPrefixPath("ParaView");
   dc.SetHighOrderOutput(true);
   dc.SetLevelsOfDetail(order);
   dc.RegisterField("u", &x);
   dc.SetCycle(0);
   dc.SetTime(0.0);
   dc.Save();

   return 0;
}
<|endoftext|>