Example #1
0
static inline void field(char & f, const Field & v, char def = '\0')
{
	f = v.empty() ? def : v[0];
}
Example #2
0
/** Compute the elastic (large!) deformation of a block of material.
 *  See problem description in ref06::PulledSheetProblem for a the boundary
 *  conditions. The problem is non-linear and therefore a Newton method is
 *  used. Moreover, the applied load (displacement or traction) is divided into
 *  load steps.
 *
 *  New features:
 *  - vectorial problem: DoFs are not scalar anymore
 *  - hyper-elasticity
 *
 */
int ref06::compressible( int argc, char * argv[] )
{
    // basic attributes of the computation
    const unsigned    geomDeg  = 1;
    const unsigned    fieldDeg = 2;
    const base::Shape shape    = base::HyperCubeShape<SPACEDIM>::value;

    // typedef mat::hypel::StVenant Material;
    typedef mat::hypel::NeoHookeanCompressible Material;

    // usage message
    if ( argc != 3 ) {
        std::cout << "Usage:  " << argv[0] << "  mesh.smf input.dat \n";
        return 0;
    }

    // read name of input file
    const std::string meshFile  = boost::lexical_cast<std::string>( argv[1] );
    const std::string inputFile = boost::lexical_cast<std::string>( argv[2] );

    // read from input file
    double E, nu, pull, traction, tolerance;
    unsigned maxIter, loadSteps;
    bool dispControlled;
    {    
        //Feed properties parser with the variables to be read
        base::io::PropertiesParser prop;
        prop.registerPropertiesVar( "E",                E );
        prop.registerPropertiesVar( "nu",               nu );
        prop.registerPropertiesVar( "pull",             pull );
        prop.registerPropertiesVar( "maxIter",          maxIter );
        prop.registerPropertiesVar( "loadSteps",        loadSteps );
        prop.registerPropertiesVar( "traction",         traction );
        prop.registerPropertiesVar( "dispControlled",   dispControlled );
        prop.registerPropertiesVar( "tolerance",        tolerance );

        // Read variables from the input file
        std::ifstream inp( inputFile.c_str()  );
        VERIFY_MSG( inp.is_open(), "Cannot open input file" );
        prop.readValues( inp );
        inp.close( );

        // Make sure all variables have been found
        if ( not prop.isEverythingRead() ) {
            prop.writeUnread( std::cerr );
            VERIFY_MSG( false, "Could not find above variables" );
        }
    }

    // find base name from mesh file
    const std::string baseName = base::io::baseName( meshFile, ".smf" );

    //--------------------------------------------------------------------------
    // define a mesh
    typedef base::Unstructured<shape,geomDeg>    Mesh;
    const unsigned dim = Mesh::Node::dim;

    // create a mesh and read from input
    Mesh mesh;
    {
        std::ifstream smf( meshFile.c_str() );
        base::io::smf::readMesh( smf, mesh );
        smf.close();
    }

    // quadrature objects for volume and surface
    const unsigned kernelDegEstimate = 3;
    typedef base::Quadrature<kernelDegEstimate,shape> Quadrature;
    Quadrature quadrature;
    typedef base::SurfaceQuadrature<kernelDegEstimate,shape> SurfaceQuadrature;
    SurfaceQuadrature surfaceQuadrature;

    // Create a field
    const unsigned    doFSize = dim;
    typedef base::fe::Basis<shape,fieldDeg>        FEBasis;
    typedef base::Field<FEBasis,doFSize>           Field;
    typedef Field::DegreeOfFreedom                 DoF;
    Field field;

    // generate DoFs from mesh
    base::dof::generate<FEBasis>( mesh, field );

    // Creates a list of <Element,faceNo> pairs along the boundary
    base::mesh::MeshBoundary meshBoundary;
    meshBoundary.create( mesh.elementsBegin(), mesh.elementsEnd() );

    // Create a boundary mesh from this list
    typedef base::mesh::BoundaryMeshBinder<Mesh::Element>::Type BoundaryMesh;
    BoundaryMesh boundaryMesh;
    {
        // Create a real mesh object from this list
        base::mesh::generateBoundaryMesh( meshBoundary.begin(),
                                          meshBoundary.end(),
                                          mesh, boundaryMesh );
    }

    // initial pull = (total amount) / (number of steps)
    const double firstPull = pull / static_cast<double>( loadSteps );

    // constrain the boundary
    base::dof::constrainBoundary<FEBasis>( meshBoundary.begin(),
                                           meshBoundary.end(),
                                           mesh, field, 
                                           boost::bind(
                                               &ref06::PulledSheet<dim>::dirichletBC<DoF>,
                                               _1, _2, dispControlled, firstPull ) );

    // Bind the fields together
    typedef base::asmb::FieldBinder<Mesh,Field> FieldBinder;
    FieldBinder fieldBinder( mesh, field );
    typedef FieldBinder::TupleBinder<1,1>::Type FTB;

    typedef base::asmb::SurfaceFieldBinder<BoundaryMesh,Field> SurfaceFieldBinder;
    SurfaceFieldBinder surfaceFieldBinder( boundaryMesh, field );
    typedef SurfaceFieldBinder::TupleBinder<1>::Type SFTB;

    // material object
    Material material( mat::Lame::lambda( E, nu), mat::Lame::mu( E, nu ) );

    // matrix kernel
    typedef solid::HyperElastic<Material,FTB::Tuple> HyperElastic;
    HyperElastic hyperElastic( material );
            
    // Number the degrees of freedom
    const std::size_t numDofs =
        base::dof::numberDoFsConsecutively( field.doFsBegin(), field.doFsEnd() );
    std::cout << "# Number of dofs " << numDofs << std::endl;

    // create table for writing the convergence behaviour of the nonlinear solves
    base::io::Table<4>::WidthArray widths = {{ 2, 5, 5, 15 }};
    base::io::Table<4> table( widths );
    table % "Step" % "Iter" % "|F|"  % "|x|";
    std::cout << "#" << table;

    // write a vtk file
    ref06::writeVTKFile( baseName, 0, mesh, field, material );


    //--------------------------------------------------------------------------
    // Loop over load steps
    //--------------------------------------------------------------------------
    for ( unsigned step = 0; step < loadSteps; step++ ) {

        // rescale constraints in every load step: (newValue / oldValue)
        const double  pullFactor =
            (step == 0 ?
             static_cast<double>( step+1 ) :
             static_cast<double>( step+1 )/ static_cast<double>(step) );

        // scale constraints
        base::dof::scaleConstraints( field, pullFactor );

        //----------------------------------------------------------------------
        // Nonlinear iterations
        //----------------------------------------------------------------------
        unsigned iter = 0;
        while ( iter < maxIter ) {

            table % step % iter;
    
            // Create a solver object
            typedef base::solver::Eigen3           Solver;
            Solver solver( numDofs );

            // apply traction boundary condition, if problem is not disp controlled
            if ( not dispControlled ) {
                
                // value of applied traction
                const double tractionFactor =
                    traction * 
                    static_cast<double>(step+1) / static_cast<double>( loadSteps );

                // apply traction load
                base::asmb::neumannForceComputation<SFTB>(
                    surfaceQuadrature, solver,
                    surfaceFieldBinder,
                    boost::bind( &ref06::PulledSheet<dim>::neumannBC,
                                 _1, _2, tractionFactor ) );
            }

            // residual forces
            base::asmb::computeResidualForces<FTB>( quadrature, solver,
                                                    fieldBinder,
                                                    hyperElastic );
            
            // Compute element stiffness matrices and assemble them
            base::asmb::stiffnessMatrixComputation<FTB>( quadrature, solver,
                                                         fieldBinder,
                                                         hyperElastic );

            // Finalise assembly
            solver.finishAssembly();

            // norm of residual 
            const double conv1 = solver.norm();
            table % conv1;

            // convergence via residual norm
            if ( conv1 < tolerance * E ) { // note the tolerance multiplier
                std::cout << table;
                break;
            }

            // Solve
            //solver.choleskySolve();
            solver.cgSolve();
            
            // distribute results back to dofs
            base::dof::addToDoFsFromSolver( solver, field );

            // norm of displacement increment
            const double conv2 = solver.norm();
            table % conv2;
            std::cout << table;
            iter++;
            
            // convergence via increment
            if ( conv2 < tolerance ) break;
        }
        // Finished non-linear iterations
        //----------------------------------------------------------------------

        // warning
        if ( iter == maxIter ) {
            std::cout << "# (WW) Step " << step << " has not converged within "
                      << maxIter << " iterations \n";
        }

        // write a vtk file
        ref06::writeVTKFile( baseName, step+1, mesh, field, material );
        
    }
    // Finished load steps
    //--------------------------------------------------------------------------
    
    return 0;
}
Example #3
0
	int removeElementsConditional(Field& conditionalField)
	{
		return Cmiss_mesh_group_remove_elements_conditional(
			reinterpret_cast<Cmiss_mesh_group_id>(id), conditionalField.getId());
	}
Example #4
0
Real VolumeIntegral::integrate(const Field& field, const std::vector< Handle<Entities> >& entities)
{
  Real local_integral = 0.;
  boost_foreach( const Handle<Entities>& patch, entities )
  {
    if( patch->element_type().dimensionality() != patch->element_type().dimension() )
      throw SetupError( FromHere(), "Cannot compute Volume integral of surface element");

    if( is_not_null(m_quadrature) )
      remove_component("quadrature");
    m_quadrature = create_component<Quadrature>("quadrature",
        "cf3.mesh.gausslegendre."+GeoShape::Convert::instance().to_str(patch->element_type().shape())+"P"+common::to_str(m_order));

    /// Common part for every element of this patch
    const Space& space = field.space(*patch);
    const Uint nb_elems = space.size();
    const Uint nb_nodes_per_elem = space.shape_function().nb_nodes();
    const Uint nb_qdr_pts = m_quadrature->nb_nodes();
    const Uint nb_vars = field.row_size();

    RealMatrix qdr_pt_values( nb_qdr_pts, nb_vars );
    RealMatrix interpolate( nb_qdr_pts, nb_nodes_per_elem );
    RealMatrix field_pt_values( nb_nodes_per_elem, nb_vars );
    RealMatrix elem_coords;

    patch->geometry_space().allocate_coordinates(elem_coords);

    for( Uint qn=0; qn<nb_qdr_pts; ++qn)
    {
      interpolate.row(qn) = space.shape_function().value( m_quadrature->local_coordinates().row(qn) );
    }

    /// Loop over every element of this patch
    for (Uint e=0; e<nb_elems; ++e)
    {
      if( ! patch->is_ghost(e) )
      {
        patch->geometry_space().put_coordinates(elem_coords,e);

        // interpolate
        for (Uint n=0; n<nb_nodes_per_elem; ++n)
        {
          const Uint p = space.connectivity()[e][n];
          for (Uint v=0; v<nb_vars; ++v)
          {
            field_pt_values(n,v) = field[p][v];
          }
        }
        qdr_pt_values = interpolate * field_pt_values;

        // integrate
        for( Uint qn=0; qn<nb_qdr_pts; ++qn)
        {
          const Real Jdet = patch->element_type().jacobian_determinant( m_quadrature->local_coordinates().row(qn), elem_coords );
          local_integral += Jdet * m_quadrature->weights()[qn] * qdr_pt_values(qn,0);
        }
      }
    }
  }
  Real global_integral;
  PE::Comm::instance().all_reduce(PE::plus(), &local_integral, 1, &global_integral);
  return global_integral;
}
Example #5
0
void WritePly(const std::vector<CVector<3,double> >& result, const Field<2,float>& mask, std::string filename)
{
	// generate face indices
	Field<2,int> index(mask.size());
	for (int y=0, idx=0; y<mask.size(1); y++)
		for (int x=0; x<mask.size(0); x++)
			if (mask.cell(x,y))
				index.cell(x,y)=idx++;
			else
				index.cell(x,y)=-1;

	std::vector<CVector<3,int> > face;
	for (int y=0; y<mask.size(1)-1; y++)
	{
		for (int x=0; x<mask.size(0)-1; x++)
		{
			// sore in CCW order
			if (mask.cell(x,y) && mask.cell(x+1,y) && mask.cell(x+1,y+1) && 
				!distorted(index.cell(x,y),index.cell(x+1,y),index.cell(x+1,y+1),result))
				face.push_back(make_vector(index.cell(x,y),index.cell(x+1,y+1),index.cell(x+1,y)));
			if (mask.cell(x,y) && mask.cell(x+1,y+1) && mask.cell(x,y+1) && 
				!distorted(index.cell(x,y),index.cell(x+1,y+1),index.cell(x,y+1),result))
				face.push_back(make_vector(index.cell(x,y),index.cell(x,y+1),index.cell(x+1,y+1)));
		}
	}

	TRACE("ply => %s\n",filename.c_str());
	FILE *fw = fopen(filename.c_str(), "wb");
	fprintf(fw,
			"ply\n"
			"format binary_little_endian 1.0\n"
			"element vertex %d\n"
			"property float x\n"
			"property float y\n"
			"property float z\n"
			"element face %d\n"
			"property list uchar int vertex_indices\n"
			"end_header\n", result.size(), face.size());
	for (int i=0; i<result.size(); i++)
	{
		CVector<3,float> p = make_vector(result[i][0],result[i][1],result[i][2]);
		fwrite(&p, 12, 1, fw);
	} 
	for (int i=0; i<face.size(); i++)
	{
		fputc(3,fw);
		fwrite(&face[i], 12, 1, fw);
	}

	fclose(fw);
}
Example #6
0
bool FieldsReader::doc(int32_t n, Document* doc)
{
    if ( n * 8L > indexStream->length() )
        return false;

    indexStream->seek(n * 8L);
    int64_t position = indexStream->readLong();
    fieldsStream->seek(position);

    int32_t numFields = fieldsStream->readVInt();
    for (int32_t i = 0; i < numFields; i++) {
        int32_t fieldNumber = fieldsStream->readVInt();
        FieldInfo* fi = fieldInfos->fieldInfo(fieldNumber);

        if ( fi == NULL )
            _CLTHROWA(CL_ERR_IO, "Field stream is invalid");

        uint8_t bits = fieldsStream->readByte();
        if ((bits & FieldsWriter::FIELD_IS_BINARY) != 0) {
            int32_t fieldLen = fieldsStream->readVInt();
            FieldsReader::FieldsStreamHolder* subStream = new
                FieldsReader::FieldsStreamHolder(fieldsStream, fieldLen);
            uint8_t bits = Field::STORE_YES;
            Field* f = _CLNEW Field(
                fi->name,   // name
                subStream,  // read value
                bits);

            doc->add(*f);

            //now skip over the rest of the field
            if (fieldsStream->getFilePointer() + fieldLen
                == fieldsStream->length()) {
                // set to eof
                fieldsStream->seek(fieldsStream->getFilePointer() + fieldLen - 1);
                fieldsStream->readByte();
            } else {
                fieldsStream->seek(fieldsStream->getFilePointer() + fieldLen);
            }
        } else {
            uint8_t bits = Field::STORE_YES;
            if (fi->isIndexed && (bits & FieldsWriter::FIELD_IS_TOKENIZED)!=0 )
                bits |= Field::INDEX_TOKENIZED;
            else if (fi->isIndexed && (bits & FieldsWriter::FIELD_IS_TOKENIZED) == 0)
                bits |= Field::INDEX_UNTOKENIZED;
            else
                bits |= Field::INDEX_NO;

            if (fi->storeTermVector) {
                if (fi->storeOffsetWithTermVector) {
                    if (fi->storePositionWithTermVector) {
                        bits |= Field::TERMVECTOR_WITH_OFFSETS;
                        bits |= Field::TERMVECTOR_WITH_POSITIONS;
                    } else {
                        bits |= Field::TERMVECTOR_WITH_OFFSETS;
                    }
                } else if (fi->storePositionWithTermVector) {
                    bits |= Field::TERMVECTOR_WITH_POSITIONS;
                } else {
                    bits |= Field::TERMVECTOR_YES;
                }
            } else {
                bits |= Field::TERMVECTOR_NO;
            }

            if ( (bits & FieldsWriter::FIELD_IS_COMPRESSED) != 0 ) {
                bits |= Field::STORE_COMPRESS;
                int32_t fieldLen = fieldsStream->readVInt();
                FieldsStreamHolder* subStream = new 
                    FieldsStreamHolder(fieldsStream, fieldLen);

                // TODO: we dont have gzip inputstream available, must alert
                // user to somehow use a gzip inputstream
                Field* f = _CLNEW Field(
                    fi->name,   // name
                    subStream,  // read value
                    bits);

                f->setOmitNorms(fi->omitNorms);
                doc->add(*f);

                // now skip over the rest of the field
                if (fieldsStream->getFilePointer() + fieldLen
                    == fieldsStream->length()) {
                    //set to eof
                    fieldsStream->seek(fieldsStream->getFilePointer() + fieldLen - 1);
                    fieldsStream->readByte();
                } else {
                    fieldsStream->seek(fieldsStream->getFilePointer() + fieldLen);
                }
            } else {
                TCHAR* fvalue = fieldsStream->readString(true);
                Field* f = _CLNEW Field(
                    fi->name,   // name
                    fvalue,     // read value
                    bits);
                // TODO: could optimise this
                _CLDELETE_CARRAY(fvalue);
                f->setOmitNorms(fi->omitNorms);
                doc->add(*f);
            }
        }
    }
    return true;
}
Example #7
0
bool fieldTest() {
	Class A(NULL, "A");
	ASSERT_NO_THROW(A.addStaticField("static", INT));
	ASSERT_EQUALS("static", A.getField("static").name());
	ASSERT_EQUALS("A", A.getField("static").getDeclaringClass());
	ASSERT_EQUALS(INT, A.getField("static").getType());
	Object* inst1 = A.newInstance();
	ASSERT_NO_THROW(A.addInstanceField("field", INT));
	Field f = A.getField("field");

	Field exist = A.getField("static");
	ASSERT_THROW(FieldNotFound, f.setInt(inst1, 4));
	ASSERT_NO_THROW(exist.setInt(inst1, 555));
	Class::setAccessible(true);

	ASSERT_THROW(FieldNotFound, f.setInt(inst1, 4));
	ASSERT_THROW(FieldNotFound, f.getInt(inst1));
	ASSERT_THROW(TypeError, f.setObj(inst1,NULL));
	ASSERT_THROW(TypeError, f.getObj(inst1));
	Object* inst2 = A.newInstance();
	ASSERT_NO_THROW(f.setInt(inst2, 17));
	ASSERT_NO_THROW(exist.getInt(inst1));
	ASSERT_EQUALS(exist.getInt(inst1), 555);
	ASSERT_EQUALS(f.getInt(inst2), 17);
	ASSERT_THROW(TypeError, f.setObj(inst2,NULL));
	ASSERT_THROW(TypeError, f.getObj(inst2));

	Class::setAccessible(false);
/*	delete inst1;
	delete inst2;*/
	return true;
}
 void operator ()(Field &f, const Data &d) {
   f.sub(f, d);
 }
void StorageDistributed::reshardPartitions(ASTPtr query, const String & database_name,
        const Field & first_partition, const Field & last_partition,
        const WeightedZooKeeperPaths & weighted_zookeeper_paths,
        const ASTPtr & sharding_key_expr, bool do_copy, const Field & coordinator,
        const Settings & settings)
{
    auto & resharding_worker = context.getReshardingWorker();
    if (!resharding_worker.isStarted())
        throw Exception{"Resharding background thread is not running", ErrorCodes::RESHARDING_NO_WORKER};

    if (!coordinator.isNull())
        throw Exception{"Use of COORDINATE WITH is forbidden in ALTER TABLE ... RESHARD"
                        " queries for distributed tables",
                        ErrorCodes::RESHARDING_INVALID_PARAMETERS};

    std::string coordinator_id = resharding_worker.createCoordinator(cluster);

    std::atomic<bool> has_notified_error{false};

    std::string dumped_coordinator_state;

    auto handle_exception = [&](const std::string & msg = "")
    {
        try
        {
            if (!has_notified_error)
                resharding_worker.setStatus(coordinator_id, ReshardingWorker::STATUS_ERROR, msg);
            dumped_coordinator_state = resharding_worker.dumpCoordinatorState(coordinator_id);
            resharding_worker.deleteCoordinator(coordinator_id);
        }
        catch (...)
        {
            tryLogCurrentException(__PRETTY_FUNCTION__);
        }
    };

    try
    {
        /// Создать запрос ALTER TABLE ... RESHARD [COPY] PARTITION ... COORDINATE WITH ...

        ASTPtr alter_query_ptr = std::make_shared<ASTAlterQuery>();
        auto & alter_query = static_cast<ASTAlterQuery &>(*alter_query_ptr);

        alter_query.database = remote_database;
        alter_query.table = remote_table;

        alter_query.parameters.emplace_back();
        ASTAlterQuery::Parameters & parameters = alter_query.parameters.back();

        parameters.type = ASTAlterQuery::RESHARD_PARTITION;
        if (!first_partition.isNull())
            parameters.partition = std::make_shared<ASTLiteral>(StringRange(), first_partition);
        if (!last_partition.isNull())
            parameters.last_partition = std::make_shared<ASTLiteral>(StringRange(), last_partition);

        ASTPtr expr_list = std::make_shared<ASTExpressionList>();
        for (const auto & entry : weighted_zookeeper_paths)
        {
            ASTPtr weighted_path_ptr = std::make_shared<ASTWeightedZooKeeperPath>();
            auto & weighted_path = static_cast<ASTWeightedZooKeeperPath &>(*weighted_path_ptr);
            weighted_path.path = entry.first;
            weighted_path.weight = entry.second;
            expr_list->children.push_back(weighted_path_ptr);
        }

        parameters.weighted_zookeeper_paths = expr_list;
        parameters.sharding_key_expr = sharding_key_expr;
        parameters.do_copy = do_copy;
        parameters.coordinator = std::make_shared<ASTLiteral>(StringRange(), Field(coordinator_id));

        resharding_worker.registerQuery(coordinator_id, queryToString(alter_query_ptr));

        /** Функциональность shard_multiplexing не доделана - выключаем её.
        * (Потому что установка соединений с разными шардами в рамках одного потока выполняется не параллельно.)
        * Подробнее смотрите в https://███████████.yandex-team.ru/METR-18300
        */
        bool enable_shard_multiplexing = false;

        ClusterProxy::AlterQueryConstructor alter_query_constructor;

        BlockInputStreams streams = ClusterProxy::Query{alter_query_constructor, cluster, alter_query_ptr,
                          context, settings, enable_shard_multiplexing} .execute();

        /// This callback is called if an exception has occurred while attempting to read
        /// a block from a shard. This is to avoid a potential deadlock if other shards are
        /// waiting inside a barrier. Actually, even without this solution, we would avoid
        /// such a deadlock because we would eventually time out while trying to get remote
        /// blocks. Nevertheless this is not the ideal way of sorting out this issue since
        /// we would then not get to know the actual cause of the failure.
        auto exception_callback = [&resharding_worker, coordinator_id, &has_notified_error]()
        {
            try
            {
                resharding_worker.setStatus(coordinator_id, ReshardingWorker::STATUS_ERROR);
                has_notified_error = true;
            }
            catch (...)
            {
                tryLogCurrentException(__PRETTY_FUNCTION__);
            }
        };

        streams[0] = std::make_shared<UnionBlockInputStream<>>(
                         streams, nullptr, settings.max_distributed_connections, exception_callback);
        streams.resize(1);

        auto stream_ptr = dynamic_cast<IProfilingBlockInputStream *>(&*streams[0]);
        if (stream_ptr == nullptr)
            throw Exception{"StorageDistributed: Internal error", ErrorCodes::LOGICAL_ERROR};
        auto & stream = *stream_ptr;

        stream.readPrefix();

        while (!stream.isCancelled() && stream.read())
            ;

        if (!stream.isCancelled())
            stream.readSuffix();
    }
    catch (const Exception & ex)
    {
        handle_exception(ex.message());
        LOG_ERROR(log, dumped_coordinator_state);
        throw;
    }
    catch (const std::exception & ex)
    {
        handle_exception(ex.what());
        LOG_ERROR(log, dumped_coordinator_state);
        throw;
    }
    catch (...)
    {
        handle_exception();
        LOG_ERROR(log, dumped_coordinator_state);
        throw;
    }
}
 void operator ()(MeterArray &meter_array, const Data &idx, Field &dst) {
   dst.set(meter_array.execute_meter(get_packet(), idx.get_uint()));
 }
 void operator ()(Field &dst, const RegisterArray &src, const Data &idx) {
   dst.set(src[idx.get_uint()]);
 }
Example #12
0
int main(int argc, char **argv)
{
	
#ifdef BENCHMARK
	//benchmarking variables
	
	double start_time, ref_time, ref2_time, cycle_start_time;
	
	double initialization_time;
	double run_time;
	double cycle_time=0;
	double projection_time = 0;
	double snapshot_output_time = 0;
	double spectra_output_time = 0;
	double gravity_solver_time = 0;
	double fft_time = 0;
	int fft_count = 0;   
	double update_q_time = 0;
	int update_q_count = 0;
	double moveParts_time = 0;
	int  moveParts_count =0;
	
#endif  //BENCHMARK
	
	int n = 0, m = 0;
	int io_size = 0;
	int io_group_size = 0;
	
	int i, j, cycle = 0, snapcount = 0, pkcount = 0, usedparams, numparam = 0, doneTT, redo_psi = 0, numsteps;
	int numsteps_ncdm[MAX_PCL_SPECIES];
	long numpts3d;
	int box[3];
	double dtau, dtau_old, dx, tau, a, fourpiG, tau_Lambda, maxvel;
	double maxvel_ncdm[MAX_PCL_SPECIES];
	FILE * outfile;
	char filename[2*PARAM_MAX_LENGTH+24];
	char buffer[64];
	string h5filename;
	char * settingsfile = NULL;
	parameter * params = NULL;
	metadata sim;
	cosmology cosmo;
	icsettings ic;
	gadget2_header hdr;
	Real * kbin;
	Real * power;
	Real * kscatter;
	Real * pscatter;
	int * occupation;
	int numbins;
	Real divB, curlB, divh, traceh, normh, T00hom;
	Cplx tempk;
	
	for (i=1 ; i < argc ; i++ ){
		if ( argv[i][0] != '-' )
			continue;
		switch(argv[i][1]) {
			case 's':
				settingsfile = argv[++i]; //settings file name
				break;
			case 'n':
				n = atoi(argv[++i]); //size of the dim 1 of the processor grid
				break;
			case 'm':
				m =  atoi(argv[++i]); //size of the dim 2 of the processor grid
				break;
			case 'i':
#ifndef EXTERNAL_IO
				cout << "EXTERNAL_IO needs to be set at compilation to use the I/O server"<<endl;
				exit(-1000);
#endif
				io_size =  atoi(argv[++i]);
				break;
			case 'g':
#ifndef EXTERNAL_IO
				cout << "EXTERNAL_IO needs to be set at compilation to use the I/O server"<<endl;
				exit(-1000);
#endif
				io_group_size = atoi(argv[++i]);
		}
	}

#ifndef EXTERNAL_IO
	parallel.initialize(n,m);
#else
	parallel.initialize(n,m,io_size,io_group_size);
	if(parallel.isIO()) ioserver.start();
	else
	{
#endif
		
	COUT << "  _   _      _         __ ,  _" << endl;
	COUT << " (_| (-' \\/ (_) (_ (_| (  ( (_) /\\/	version 1.0    running on " << n*m << " cores." << endl;
	COUT << "  -'" << endl << endl;
	
	if (settingsfile == NULL)
	{
		COUT << " error: no settings file specified!" << endl;
		parallel.abortForce();
	}
	
	COUT << " initializing..." << endl;
	
#ifdef BENCHMARK
	start_time = MPI_Wtime();
#endif
	
	
	numparam = loadParameterFile(settingsfile, params);
	
	usedparams = parseMetadata(params, numparam, sim, cosmo, ic);
	
	COUT << " parsing of settings file completed. " << numparam << " parameters found, " << usedparams << " were used." << endl;
	
	sprintf(filename, "%s%s_settings_used.ini", sim.output_path, sim.basename_generic);
	saveParameterFile(filename, params, numparam);
	
	free(params);
	
	h5filename.reserve(2*PARAM_MAX_LENGTH);
	h5filename.assign(sim.output_path);
	h5filename += sim.basename_snapshot;
	
	box[0] = sim.numpts;
	box[1] = sim.numpts;
	box[2] = sim.numpts;
	
	Lattice lat(3,box,1);
	Lattice latFT;
	latFT.initializeRealFFT(lat,0);
	
	Particles_gevolution<part_simple,part_simple_info,part_simple_dataType> pcls_cdm;
	Particles_gevolution<part_simple,part_simple_info,part_simple_dataType> pcls_ncdm[MAX_PCL_SPECIES];
	Field<Real> * update_cdm_fields[3];
	Field<Real> * update_ncdm_fields[3];
	double f_params[5];

	Field<Real> phi;
	Field<Real> psi;
	Field<Real> source;
	Field<Real> chi;
	Field<Real> Sij;
	Field<Real> Bi;
	Field<Cplx> scalarFT;
	Field<Cplx> SijFT;
	Field<Cplx> BiFT;
	source.initialize(lat,1);
	psi.initialize(lat,1);
	phi.initialize(lat,1);
	chi.initialize(lat,1);
	scalarFT.initialize(latFT,1);
	PlanFFT<Cplx> plan_source(&source, &scalarFT);
	PlanFFT<Cplx> plan_psi(&psi, &scalarFT);
	PlanFFT<Cplx> plan_phi(&phi, &scalarFT);
	PlanFFT<Cplx> plan_chi(&chi, &scalarFT);
	Sij.initialize(lat,3,3,symmetric);
	SijFT.initialize(latFT,3,3,symmetric);
	PlanFFT<Cplx> plan_Sij(&Sij, &SijFT);
	Bi.initialize(lat,3);
	BiFT.initialize(latFT,3);
	PlanFFT<Cplx> plan_Bi(&Bi, &BiFT);
#ifdef CHECK_B
	Field<Real> Bi_check;
	Field<Cplx> BiFT_check;
	Bi_check.initialize(lat,3);
	BiFT_check.initialize(latFT,3);
	PlanFFT<Cplx> plan_Bi_check(&Bi_check, &BiFT_check);
#endif

	update_cdm_fields[0] = &psi;
	update_cdm_fields[1] = &phi;
	update_cdm_fields[2] = &Bi;
	
	update_ncdm_fields[0] = &psi;
	update_ncdm_fields[1] = &phi;
	update_ncdm_fields[2] = &Bi;
	
	Site x(lat);
	rKSite kFT(latFT);
	
	dx = 1.0 / (double) sim.numpts;
	numpts3d = (long) sim.numpts * (long) sim.numpts * (long) sim.numpts;
	
	for (i = 0; i < 3; i++) // particles may never move farther than to the adjacent domain
	{
		if (lat.sizeLocal(i)-1 < sim.movelimit)
			sim.movelimit = lat.sizeLocal(i)-1;
	}
	parallel.min(sim.movelimit);

	fourpiG = 1.5 * sim.boxsize * sim.boxsize / 2997.92458 / 2997.92458;
	a = 1. / (1. + sim.z_in);
	tau = 2. / Hconf(a, fourpiG, cosmo);
	tau_Lambda = -1.0;
	
	if (sim.Cf * dx < sim.steplimit / Hconf(a, fourpiG, cosmo))
		dtau = sim.Cf * dx;
	else
		dtau = sim.steplimit / Hconf(a, fourpiG, cosmo);
		
	dtau_old = dtau;
	
	if (ic.generator == ICGEN_BASIC)
		maxvel = generateIC_basic(sim, ic, cosmo, fourpiG, dtau, &pcls_cdm, pcls_ncdm, maxvel_ncdm, &phi, &psi, &chi, &Bi, &source, &Sij, &scalarFT, &BiFT, &SijFT, &plan_phi, &plan_psi, &plan_chi, &plan_Bi, &plan_source, &plan_Sij); // generates ICs on the fly
#ifdef ICGEN_PREVOLUTION
	else if (ic.generator == ICGEN_PREVOLUTION)
	{
		maxvel = generateIC_prevolution(sim, ic, cosmo, fourpiG, a, &pcls_cdm, pcls_ncdm, maxvel_ncdm, &phi, &psi, &chi, &Bi, &source, &Sij, &scalarFT, &BiFT, &SijFT, &plan_phi, &plan_psi, &plan_chi, &plan_Bi, &plan_source, &plan_Sij);
	}
#endif
#ifdef ICGEN_FALCONIC
	else if (ic.generator == ICGEN_FALCONIC)
	{
		maxvel = generateIC_FalconIC(sim, ic, cosmo, fourpiG, dtau, &pcls_cdm, pcls_ncdm, maxvel_ncdm, &phi, &psi, &chi, &Bi, &source, &Sij, &scalarFT, &BiFT, &SijFT, &plan_phi, &plan_psi, &plan_chi, &plan_Bi, &plan_source, &plan_Sij);
	}
#endif
	else
	{
		COUT << " error: IC generator not implemented!" << endl;
		parallel.abortForce();
	}
	
	parallel.max<double>(maxvel);	
	if (cosmo.num_ncdm > 0) parallel.max<double>(maxvel_ncdm, cosmo.num_ncdm);
	
	if (sim.gr_flag > 0)
	{
		maxvel /= sqrt(maxvel * maxvel + 1.0);
		for (i = 0; i < cosmo.num_ncdm; i++)
			maxvel_ncdm[i] /= sqrt(maxvel_ncdm[i] * maxvel_ncdm[i] + 1.0);
	}
	
	kbin = (Real *) malloc(sim.numbins * sizeof(Real));
	power = (Real *) malloc(sim.numbins * sizeof(Real));
	kscatter = (Real *) malloc(sim.numbins * sizeof(Real));
	pscatter = (Real *) malloc(sim.numbins * sizeof(Real));
	occupation = (int *) malloc(sim.numbins * sizeof(int));
	
	for (i = 0; i < 6; i++)
	{
		hdr.npart[i] = 0;
		hdr.npartTotal[i] = 0;
		hdr.mass[i] = 0.;
	}
	hdr.num_files = 1;
	hdr.Omega0 = cosmo.Omega_m;
	hdr.OmegaLambda = 1. - cosmo.Omega_m;
	hdr.HubbleParam = cosmo.h;
	hdr.BoxSize = sim.boxsize * 1000.;
	hdr.flag_sfr = 0;
	hdr.flag_cooling = 0;
	hdr.flag_feedback = 0;
	for (i = 0; i < 256 - 6 * 4 - 6 * 8 - 2 * 8 - 2 * 4 - 6 * 4 - 2 * 4 - 4 * 8; i++)
		hdr.fill[i] = 0;
	
#ifdef BENCHMARK
	initialization_time = MPI_Wtime() - start_time;
	parallel.sum(initialization_time);
	COUT << " initialization complete. BENCHMARK: " << hourMinSec(initialization_time) << endl << endl;
#else
	COUT << " initialization complete." << endl << endl;
#endif
	
	while (true)    // main loop
	{
#ifdef BENCHMARK		
		cycle_start_time = MPI_Wtime();
#endif
		// construct stress-energy tensor
		projection_init(&source);
		if (sim.gr_flag > 0)
		{
			projection_T00_project(&pcls_cdm, &source, a, &phi);
			for (i = 0; i < cosmo.num_ncdm; i++)
				projection_T00_project(pcls_ncdm+i, &source, a, &phi);
		}
		else
		{
			scalarProjectionCIC_project(&pcls_cdm, &source);
			for (i = 0; i < cosmo.num_ncdm; i++)
				scalarProjectionCIC_project(pcls_ncdm+i, &source);
		}
		projection_T00_comm(&source);
		
		projection_init(&Sij);
		projection_Tij_project(&pcls_cdm, &Sij, a, &phi);
		for (i = 0; i < cosmo.num_ncdm; i++)
			projection_Tij_project(pcls_ncdm+i, &Sij, a, &phi);
		projection_Tij_comm(&Sij);
		
		doneTT = 0;
		
#ifdef BENCHMARK 
		projection_time += MPI_Wtime() - cycle_start_time;
		ref_time = MPI_Wtime();
#endif
		// snapshot output
		if (snapcount < sim.num_snapshot && 1. / a < sim.z_snapshot[snapcount] + 1.)
		{
			sprintf(filename, "%03d", snapcount);
			snapcount++;
			
			COUT << " writing snapshot at z = " << ((1./a) - 1.) <<  " (cycle " << cycle << "), tau/boxsize = " << tau << endl;
			
#ifdef EXTERNAL_IO
			while (ioserver.openOstream()== OSTREAM_FAIL);
			
			if (sim.out_snapshot & MASK_PCLS)
				pcls_cdm.saveHDF5_server_open(h5filename + filename + "_part");
				
			if (sim.out_snapshot & MASK_DBARE && sim.gr_flag > 0)
				psi.saveHDF5_server_open(h5filename + filename + "_deltaN");
			
			if (sim.out_snapshot & MASK_T00)
				source.saveHDF5_server_open(h5filename + filename + "_T00");
				
			if (sim.out_snapshot & MASK_B)
				Bi.saveHDF5_server_open(h5filename + filename + "_B");
			
			if (sim.out_snapshot & MASK_PHI)
				phi.saveHDF5_server_open(h5filename + filename + "_phi");
				
			if (sim.out_snapshot & MASK_CHI)
				chi.saveHDF5_server_open(h5filename + filename + "_chi");
			
			if (sim.out_snapshot & MASK_HIJ)
				Sij.saveHDF5_server_open(h5filename + filename + "_hij");
				
#ifdef CHECK_B
			if (sim.out_snapshot & MASK_B)
				Bi_check.saveHDF5_server_open(h5filename + filename + "_B_check");
#endif
#endif		
			
			if (sim.out_snapshot & MASK_DBARE)
			{
				if (sim.gr_flag > 0)
				{   
					projection_init(&psi);
					scalarProjectionCIC_project(&pcls_cdm, &psi);
					for (i = 0; i < cosmo.num_ncdm; i++)
						scalarProjectionCIC_project(pcls_ncdm+i, &psi);
					scalarProjectionCIC_comm(&psi);
#ifdef EXTERNAL_IO
					psi.saveHDF5_server_write(NUMBER_OF_IO_FILES);
#else
					psi.saveHDF5(h5filename + filename + "_deltaN.h5");
#endif
					redo_psi = 1;
				}
				else
					source.saveHDF5(h5filename + filename + "_deltaN.h5");
			}
			
			if (sim.out_snapshot & MASK_POT)
			{
				if (!redo_psi)
				{
					projection_init(&psi);
					scalarProjectionCIC_project(&pcls_cdm, &psi);
					for (i = 0; i < cosmo.num_ncdm; i++)
						scalarProjectionCIC_project(pcls_ncdm+i, &psi);
					scalarProjectionCIC_comm(&psi);
					redo_psi = 1;
				}
				plan_psi.execute(FFT_FORWARD);				
				solveModifiedPoissonFT(scalarFT, scalarFT, fourpiG / a);
				plan_psi.execute(FFT_BACKWARD);
				psi.saveHDF5(h5filename + filename + "_psiN.h5");
			}
				
			if (sim.out_snapshot & MASK_T00)
#ifdef EXTERNAL_IO
				source.saveHDF5_server_write(NUMBER_OF_IO_FILES);
#else
				source.saveHDF5(h5filename + filename + "_T00.h5");
#endif
				
			if (sim.out_snapshot & MASK_B)
			{
				if (sim.gr_flag == 0)
				{
					plan_Bi.execute(FFT_BACKWARD);
				}
				for (x.first(); x.test(); x.next())
				{
					Bi(x,0) /= a * a * sim.numpts;
					Bi(x,1) /= a * a * sim.numpts;
					Bi(x,2) /= a * a * sim.numpts;
				}
				Bi.updateHalo();
				
				computeVectorDiagnostics(Bi, divB, curlB);			
				COUT << " B diagnostics: max |divB| = " << divB << ", max |curlB| = " << curlB << endl;

#ifdef EXTERNAL_IO
				Bi.saveHDF5_server_write(NUMBER_OF_IO_FILES);
#else				
				Bi.saveHDF5(h5filename + filename + "_B.h5");
#endif
				
				if (sim.gr_flag > 0)
				{
					plan_Bi.execute(FFT_BACKWARD);
					Bi.updateHalo();
				}
			}
			
			if (sim.out_snapshot & MASK_PHI)
#ifdef EXTERNAL_IO
				phi.saveHDF5_server_write(NUMBER_OF_IO_FILES);
#else
				phi.saveHDF5(h5filename + filename + "_phi.h5");
#endif
				
			if (sim.out_snapshot & MASK_CHI)
#ifdef EXTERNAL_IO
				chi.saveHDF5_server_write(NUMBER_OF_IO_FILES);
#else	
				chi.saveHDF5(h5filename + filename + "_chi.h5");
#endif
				
			if (sim.out_snapshot & MASK_TIJ)	 
				Sij.saveHDF5(h5filename + filename + "_Tij.h5");
				
			if (sim.out_snapshot & MASK_HIJ)
			{
				projectFTtensor(SijFT, SijFT);
				doneTT = 1;
				plan_Sij.execute(FFT_BACKWARD);
				Sij.updateHalo();
				
				computeTensorDiagnostics(Sij, divh, traceh, normh);
				COUT << " GW diagnostics: max |divh| = " << divh << ", max |traceh| = " << traceh << ", max |h| = " << normh << endl;

#ifdef EXTERNAL_IO
				Sij.saveHDF5_server_write(NUMBER_OF_IO_FILES);
#else				
				Sij.saveHDF5(h5filename + filename + "_hij.h5");
#endif
				
				projection_init(&Sij);
				projection_Tij_project(&pcls_cdm, &Sij, a, &phi);
				for (i = 0; i < cosmo.num_ncdm; i++)
					projection_Tij_project(pcls_ncdm+i, &Sij, a, &phi);
				projection_Tij_comm(&Sij);
			}
			
			if (sim.out_snapshot & MASK_P)
			{
#ifdef CHECK_B
				projection_init(&Bi_check);
				vectorProjectionCICNGP_project(&pcls_cdm, &Bi_check);
				for (i = 0; i < cosmo.num_ncdm; i++)
					vectorProjectionCICNGP_project(pcls_ncdm+i, &Bi_check);
				vectorProjectionCICNGP_comm(&Bi_check);
				Bi_check.saveHDF5(h5filename + filename + "_p.h5");
#else
				projection_init(&Bi);
				vectorProjectionCICNGP_project(&pcls_cdm, &Bi);
				for (i = 0; i < cosmo.num_ncdm; i++)
					vectorProjectionCICNGP_project(pcls_ncdm+i, &Bi);
				vectorProjectionCICNGP_comm(&Bi);
				Bi.saveHDF5(h5filename + filename + "_p.h5");
				if (sim.gr_flag > 0)
				{
					plan_Bi.execute(FFT_BACKWARD);
					Bi.updateHalo();
				}
#endif
			}
				
#ifdef CHECK_B
			if (sim.out_snapshot & MASK_B)
			{
				if (!(sim.out_snapshot & MASK_P))
				{
					projection_init(&Bi_check);
					vectorProjectionCICNGP_project(&pcls_cdm, &Bi_check);
					for (i = 0; i < cosmo.num_ncdm; i++)
						vectorProjectionCICNGP_project(pcls_ncdm+i, &Bi_check);
					vectorProjectionCICNGP_comm(&Bi_check);
				}
				plan_Bi_check.execute(FFT_FORWARD);
				projectFTvector(BiFT_check, BiFT_check, fourpiG * dx * dx);
				plan_Bi_check.execute(FFT_BACKWARD);
			
				for (x.first(); x.test(); x.next())
				{
					Bi_check(x,0) /= a * a * sim.numpts;
					Bi_check(x,1) /= a * a * sim.numpts;
					Bi_check(x,2) /= a * a * sim.numpts;
				}
#ifdef EXTERNAL_IO
				Bi_check.saveHDF5_server_write(NUMBER_OF_IO_FILES);
#else
				Bi_check.saveHDF5(h5filename + filename + "_B_check.h5");
#endif
			}
#endif

			if (sim.out_snapshot & MASK_GADGET)
			{
				hdr.time = a;
				hdr.redshift = (1./a) - 1.;
				
				hdr.npart[1] = (unsigned int) (sim.numpcl[0] / sim.tracer_factor[0]);
				hdr.npartTotal[1] = hdr.npart[1];
				hdr.mass[1] = (double) sim.tracer_factor[0] * 27.7459457 * (cosmo.Omega_cdm + cosmo.Omega_b) * sim.boxsize * sim.boxsize * sim.boxsize / sim.numpcl[0];
				pcls_cdm.saveGadget2(h5filename + filename + "_part.dat", hdr, sim.tracer_factor[0]);
				for (i = 0; i < cosmo.num_ncdm; i++)
				{
					sprintf(buffer, "_ncdm%d.dat", i);
					hdr.npart[1] = (unsigned int) (sim.numpcl[i+1] / sim.tracer_factor[i+1]);
					hdr.npartTotal[1] = hdr.npart[1];
					hdr.mass[1] = (double) sim.tracer_factor[i+1] * 27.7459457 * cosmo.Omega_ncdm[i] * sim.boxsize * sim.boxsize * sim.boxsize / sim.numpcl[i+1];
					pcls_ncdm[i].saveGadget2(h5filename + filename + buffer, hdr, sim.tracer_factor[i+1]);
				}
			}
			
			if (sim.out_snapshot & MASK_PCLS)
			{
#ifdef EXTERNAL_IO
				pcls_cdm.saveHDF5_server_write();
#else
				pcls_cdm.saveHDF5(h5filename + filename + "_part", 1);
#endif
			}
			
#ifdef EXTERNAL_IO
			ioserver.closeOstream();
#endif	
		}   // snapshot output done
		
#ifdef BENCHMARK
		snapshot_output_time += MPI_Wtime() - ref_time;
		ref_time = MPI_Wtime();
#endif
		
		// power spectra
		if (pkcount < sim.num_pk && 1. / a < sim.z_pk[pkcount] + 1.)
		{
			pkcount++;
			
			COUT << " writing power spectra at z = " << ((1./a) - 1.) <<  " (cycle " << cycle << "), tau/boxsize = " << tau << endl;
			
			if (sim.out_pk & MASK_DBARE || sim.out_pk & MASK_POT || (sim.out_pk & MASK_T00 && sim.gr_flag == 0))
			{
				if (!redo_psi && sim.gr_flag > 0)
				{
					projection_init(&psi);
					scalarProjectionCIC_project(&pcls_cdm, &psi);
					for (i = 0; i < cosmo.num_ncdm; i++)
						scalarProjectionCIC_project(pcls_ncdm+i, &psi);
					scalarProjectionCIC_comm(&psi);
					redo_psi = 1;
					plan_psi.execute(FFT_FORWARD);
				}
				else if (sim.gr_flag > 0)
				{
					plan_psi.execute(FFT_FORWARD);
				}
				else
				{
					plan_source.execute(FFT_FORWARD);
				}
				
				if (sim.out_pk & MASK_DBARE || (sim.out_pk & MASK_T00 && sim.gr_flag == 0))
					extractPowerSpectrum(scalarFT, kbin, power, kscatter, pscatter, occupation, sim.numbins, true, KTYPE_LINEAR);
				
				if (sim.out_pk & MASK_DBARE)
				{
					sprintf(filename, "%s%s%03d_deltaN.dat", sim.output_path, sim.basename_pk, pkcount-1);
					writePowerSpectrum(kbin, power, kscatter, pscatter, occupation, sim.numbins, sim.boxsize, (Real) numpts3d * (Real) numpts3d * 2. * M_PI * M_PI, filename, "power spectrum of delta", a);
				}
				
				if (sim.out_pk & MASK_T00 && sim.gr_flag == 0)
				{
					sprintf(filename, "%s%s%03d_T00.dat", sim.output_path, sim.basename_pk, pkcount-1);
					writePowerSpectrum(kbin, power, kscatter, pscatter, occupation, sim.numbins, sim.boxsize, (Real) numpts3d * (Real) numpts3d * 2. * M_PI * M_PI, filename, "power spectrum of T00", a);
				}
				
				if (sim.out_pk & MASK_POT)
				{
					solveModifiedPoissonFT(scalarFT, scalarFT, fourpiG / a);
					extractPowerSpectrum(scalarFT, kbin, power, kscatter, pscatter, occupation, sim.numbins, false, KTYPE_LINEAR);
					sprintf(filename, "%s%s%03d_psiN.dat", sim.output_path, sim.basename_pk, pkcount-1);
					writePowerSpectrum(kbin, power, kscatter, pscatter, occupation, sim.numbins, sim.boxsize, (Real) numpts3d * (Real) numpts3d * 2. * M_PI * M_PI, filename, "power spectrum of psi_N", a);
				}
				
				if (cosmo.num_ncdm > 0 && (sim.out_pk & MASK_DBARE || (sim.out_pk & MASK_T00 && sim.gr_flag == 0)))
				{
					redo_psi = 1;
					projection_init(&psi);
					scalarProjectionCIC_project(&pcls_cdm, &psi);
					scalarProjectionCIC_comm(&psi);
					plan_psi.execute(FFT_FORWARD);
					extractPowerSpectrum(scalarFT, kbin, power, kscatter, pscatter, occupation, sim.numbins, false, KTYPE_LINEAR);
					sprintf(filename, "%s%s%03d_cdm.dat", sim.output_path, sim.basename_pk, pkcount-1);
					writePowerSpectrum(kbin, power, kscatter, pscatter, occupation, sim.numbins, sim.boxsize, (Real) numpts3d * (Real) numpts3d * 2. * M_PI * M_PI, filename, "power spectrum of delta for cdm", a);
					for (i = 0; i < cosmo.num_ncdm; i++)
					{
						projection_init(&psi);
						scalarProjectionCIC_project(pcls_ncdm+i, &psi);
						scalarProjectionCIC_comm(&psi);
						plan_psi.execute(FFT_FORWARD);
						extractPowerSpectrum(scalarFT, kbin, power, kscatter, pscatter, occupation, sim.numbins, false, KTYPE_LINEAR);
						sprintf(filename, "%s%s%03d_ncdm%d.dat", sim.output_path, sim.basename_pk, pkcount-1, i);
						sprintf(buffer, "power spectrum of delta for ncdm %d", i);
						writePowerSpectrum(kbin, power, kscatter, pscatter, occupation, sim.numbins, sim.boxsize, (Real) numpts3d * (Real) numpts3d * 2. * M_PI * M_PI, filename, buffer, a);
#ifdef CHECK_B
						// store k-space information for cross-spectra using BiFT_check as temporary array
						if (cosmo.num_ncdm > 1 && i < cosmo.num_ncdm-1 && i < 3)
						{
							for (kFT.first(); kFT.test(); kFT.next())
								BiFT_check(kFT, i) = scalarFT(kFT);
						}
#endif						
					}
#ifdef CHECK_B
					for (i = 0; i < cosmo.num_ncdm-1 && i < 3; i++)
					{
						if (i > 0)
						{
							for (kFT.first(); kFT.test(); kFT.next())
								scalarFT(kFT) = BiFT_check(kFT, i);
						}
						for (j = i+1; j < cosmo.num_ncdm && j <= 3; j++)
						{   
							if (j > i+1)
							{
								for (kFT.first(); kFT.test(); kFT.next())
								{
									tempk = BiFT_check(kFT, 0);
									BiFT_check(kFT, 0) = BiFT_check(kFT, j-1);
									BiFT_check(kFT, j-1) = tempk;
								}
							}
							
							extractCrossSpectrum(scalarFT, BiFT_check, kbin, power, kscatter, pscatter, occupation, sim.numbins, false, KTYPE_LINEAR);
							sprintf(filename, "%s%s%03d_ncdm%dx%d.dat", sim.output_path, sim.basename_pk, pkcount-1, i, j);
							if (cosmo.num_ncdm < 4)
								sprintf(buffer, "cross power spectrum of delta for ncdm %d x %d", (i+cosmo.num_ncdm-1)%cosmo.num_ncdm, (j+cosmo.num_ncdm-1)%cosmo.num_ncdm);
							else
								sprintf(buffer, "cross power spectrum of delta for ncdm %d x %d", (6-11*i+5*i*i)/2, i ? 4-j : (j+3)%4);
							writePowerSpectrum(kbin, power, kscatter, pscatter, occupation, sim.numbins, sim.boxsize, (Real) numpts3d * (Real) numpts3d * 2. * M_PI * M_PI, filename, buffer, a);
						}
					}
#endif
				}
			}
			
			if (sim.out_pk & MASK_PHI)
			{
				plan_phi.execute(FFT_FORWARD);
				extractPowerSpectrum(scalarFT, kbin, power, kscatter, pscatter, occupation, sim.numbins, false, KTYPE_LINEAR);
				sprintf(filename, "%s%s%03d_phi.dat", sim.output_path, sim.basename_pk, pkcount-1);
				writePowerSpectrum(kbin, power, kscatter, pscatter, occupation, sim.numbins, sim.boxsize, (Real) numpts3d * (Real) numpts3d * 2. * M_PI * M_PI, filename, "power spectrum of phi", a);
			}
			
			if (sim.out_pk & MASK_CHI)
			{
				plan_chi.execute(FFT_FORWARD);
				extractPowerSpectrum(scalarFT, kbin, power, kscatter, pscatter, occupation, sim.numbins, false, KTYPE_LINEAR);
				sprintf(filename, "%s%s%03d_chi.dat", sim.output_path, sim.basename_pk, pkcount-1);
				writePowerSpectrum(kbin, power, kscatter, pscatter, occupation, sim.numbins, sim.boxsize, (Real) numpts3d * (Real) numpts3d * 2. * M_PI * M_PI, filename, "power spectrum of chi", a);
			}
			
			if (sim.out_pk & MASK_HIJ)
			{
				if (!doneTT)
					projectFTtensor(SijFT, SijFT);
				extractPowerSpectrum(SijFT, kbin, power, kscatter, pscatter, occupation, sim.numbins, false, KTYPE_LINEAR);
				sprintf(filename, "%s%s%03d_hij.dat", sim.output_path, sim.basename_pk, pkcount-1);
				writePowerSpectrum(kbin, power, kscatter, pscatter, occupation, sim.numbins, sim.boxsize, 2. * M_PI * M_PI, filename, "power spectrum of hij", a);
			}
			
			if (sim.out_pk & MASK_T00 && sim.gr_flag > 0)
			{
				plan_source.execute(FFT_FORWARD);
				extractPowerSpectrum(scalarFT, kbin, power, kscatter, pscatter, occupation, sim.numbins, true, KTYPE_LINEAR);
				sprintf(filename, "%s%s%03d_T00.dat", sim.output_path, sim.basename_pk, pkcount-1);
				writePowerSpectrum(kbin, power, kscatter, pscatter, occupation, sim.numbins, sim.boxsize, (Real) numpts3d * (Real) numpts3d * 2. * M_PI * M_PI, filename, "power spectrum of T00", a);
				
				if (cosmo.num_ncdm > 0)
				{
					redo_psi = 1;
					projection_init(&psi);
					projection_T00_project(&pcls_cdm, &psi, a, &phi);
					projection_T00_comm(&psi);
					plan_psi.execute(FFT_FORWARD);
					extractPowerSpectrum(scalarFT, kbin, power, kscatter, pscatter, occupation, sim.numbins, false, KTYPE_LINEAR);
					sprintf(filename, "%s%s%03d_T00cdm.dat", sim.output_path, sim.basename_pk, pkcount-1);
					writePowerSpectrum(kbin, power, kscatter, pscatter, occupation, sim.numbins, sim.boxsize, (Real) numpts3d * (Real) numpts3d * 2. * M_PI * M_PI, filename, "power spectrum of T00 for cdm", a);
					for (i = 0; i < cosmo.num_ncdm; i++)
					{
						projection_init(&psi);
						projection_T00_project(pcls_ncdm+i, &psi, a, &phi);
						projection_T00_comm(&psi);
						plan_psi.execute(FFT_FORWARD);
						extractPowerSpectrum(scalarFT, kbin, power, kscatter, pscatter, occupation, sim.numbins, false, KTYPE_LINEAR);
						sprintf(filename, "%s%s%03d_T00ncdm%d.dat", sim.output_path, sim.basename_pk, pkcount-1, i);
						sprintf(buffer, "power spectrum of T00 for ncdm %d", i);
						writePowerSpectrum(kbin, power, kscatter, pscatter, occupation, sim.numbins, sim.boxsize, (Real) numpts3d * (Real) numpts3d * 2. * M_PI * M_PI, filename, buffer, a);						
#ifdef CHECK_B
						// store k-space information for cross-spectra using BiFT_check as temporary array
						if (cosmo.num_ncdm > 1 && i < 3)
						{
							for (kFT.first(); kFT.test(); kFT.next())
								BiFT_check(kFT, i) = scalarFT(kFT);
						}
#endif
					}
#ifdef CHECK_B
					for (i = 0; i < cosmo.num_ncdm-1 && i < 3; i++)
					{
						if (i > 0)
						{
							for (kFT.first(); kFT.test(); kFT.next())
								scalarFT(kFT) = BiFT_check(kFT, i);
						}
						for (j = i+1; j < cosmo.num_ncdm && j <=3; j++)
						{   
							if (j > i+1)
							{
								for (kFT.first(); kFT.test(); kFT.next())
								{
									tempk = BiFT_check(kFT, 0);
									BiFT_check(kFT, 0) = BiFT_check(kFT, j-1);
									BiFT_check(kFT, j-1) = tempk;
								}
							}
							
							extractCrossSpectrum(scalarFT, BiFT_check, kbin, power, kscatter, pscatter, occupation, sim.numbins, false, KTYPE_LINEAR);
							sprintf(filename, "%s%s%03d_T00ncdm%dx%d.dat", sim.output_path, sim.basename_pk, pkcount-1, i, j);
							if (cosmo.num_ncdm < 4)
								sprintf(buffer, "cross power spectrum of T00 for ncdm %d x %d", (i+cosmo.num_ncdm-1)%cosmo.num_ncdm, (j+cosmo.num_ncdm-1)%cosmo.num_ncdm);
							else
								sprintf(buffer, "cross power spectrum of T00 for ncdm %d x %d", (6-11*i+5*i*i)/2, i ? 4-j : (j+3)%4);
							writePowerSpectrum(kbin, power, kscatter, pscatter, occupation, sim.numbins, sim.boxsize, (Real) numpts3d * (Real) numpts3d * 2. * M_PI * M_PI, filename, buffer, a);
						}
					}
#endif
				}
			}
			
			if (sim.out_pk & MASK_B)
			{
				extractPowerSpectrum(BiFT, kbin, power, kscatter, pscatter, occupation, sim.numbins, false, KTYPE_LINEAR);
				sprintf(filename, "%s%s%03d_B.dat", sim.output_path, sim.basename_pk, pkcount-1);
				writePowerSpectrum(kbin, power, kscatter, pscatter, occupation, sim.numbins, sim.boxsize, a * a * a * a * sim.numpts * sim.numpts * 2. * M_PI * M_PI, filename, "power spectrum of B", a);
			
#ifdef CHECK_B
				projection_init(&Bi_check);
				vectorProjectionCICNGP_project(&pcls_cdm,&Bi_check);
				for (i = 0; i < cosmo.num_ncdm; i++)
					vectorProjectionCICNGP_project(pcls_ncdm+i, &Bi_check);
				vectorProjectionCICNGP_comm(&Bi_check);
				plan_Bi_check.execute(FFT_FORWARD);
				projectFTvector(BiFT_check, BiFT_check, fourpiG * dx * dx);
				extractPowerSpectrum(BiFT_check, kbin, power, kscatter, pscatter, occupation, sim.numbins, false, KTYPE_LINEAR);
				sprintf(filename, "%s%s%03d_B_check.dat", sim.output_path, sim.basename_pk, pkcount-1);
				writePowerSpectrum(kbin, power, kscatter, pscatter, occupation, sim.numbins, sim.boxsize, a * a * a * a * sim.numpts * sim.numpts * 2. * M_PI * M_PI, filename, "power spectrum of B", a);
#endif
			}		
		}   // power spectra done
		
#ifdef BENCHMARK
		spectra_output_time += MPI_Wtime() - ref_time;
		ref_time = MPI_Wtime();
#endif	  
		
		if (sim.gr_flag > 0)
		{
			if (redo_psi)
			{
				for (x.first(); x.test(); x.next())
					psi(x) = phi(x) - chi(x);					
				redo_psi = 0;
			}
			
			T00hom = 0.;
			for (x.first(); x.test(); x.next())
				T00hom += source(x);
			parallel.sum<Real>(T00hom);
			T00hom /= (Real) numpts3d;
			
			if (cycle % 10 == 0)
			{
				COUT << " cycle " << cycle << ", background information: z = " << (1./a) - 1. << ", average T00 = " << T00hom << ", background model = " << cosmo.Omega_cdm + cosmo.Omega_b + bg_ncdm(a, cosmo) << endl;
			}
			
			prepareFTsource<Real>(phi, psi, source, cosmo.Omega_cdm + cosmo.Omega_b + bg_ncdm(a, cosmo), source, 3. * Hconf(a, fourpiG, cosmo) * dx * dx / dtau_old, fourpiG * dx * dx / a, 3. * Hconf(a, fourpiG, cosmo) * Hconf(a, fourpiG, cosmo) * dx * dx);  // prepare nonlinear source for phi update

#ifdef BENCHMARK
			ref2_time= MPI_Wtime();
#endif
			plan_source.execute(FFT_FORWARD);  // go to k-space
#ifdef BENCHMARK
			fft_time += MPI_Wtime() - ref2_time;
			fft_count++;
#endif
		
			solveModifiedPoissonFT(scalarFT, scalarFT, 1. / (dx * dx), 3. * Hconf(a, fourpiG, cosmo) / dtau_old);  // phi update (k-space)
		}
		else
		{
#ifdef BENCHMARK
			ref2_time= MPI_Wtime();
#endif
			plan_source.execute(FFT_FORWARD);  // Newton: directly go to k-space
#ifdef BENCHMARK
			fft_time += MPI_Wtime() - ref2_time;
			fft_count++;
#endif
		
			solveModifiedPoissonFT(scalarFT, scalarFT, fourpiG / a);  // Newton: phi update (k-space)
		}

#ifdef BENCHMARK
		ref2_time= MPI_Wtime();
#endif		
		plan_phi.execute(FFT_BACKWARD);	 // go back to position space
#ifdef BENCHMARK
		fft_time += MPI_Wtime() - ref2_time;
		fft_count++;
#endif	
		phi.updateHalo();  // communicate halo values

		// record some background data
		if (kFT.setCoord(0, 0, 0))
		{
			sprintf(filename, "%s%s_background.dat", sim.output_path, sim.basename_generic);
			outfile = fopen(filename, "a");
			if (outfile == NULL)
			{
				cout << " error opening file for background output!" << endl;
			}
			else
			{
				if (cycle == 0)
					fprintf(outfile, "# background statistics\n# cycle   tau/boxsize    a             conformal H/H0  phi(k=0)       T00(k=0)\n");
				fprintf(outfile, " %6d   %e   %e   %e   %e   %e\n", cycle, tau, a, Hconf(a, fourpiG, cosmo) / Hconf(1., fourpiG, cosmo), scalarFT(kFT).real(), T00hom);
				fclose(outfile);
			}
		}
		// done recording background data

		if (pkcount >= sim.num_pk && snapcount >= sim.num_snapshot) break; // simulation complete   
		
		prepareFTsource<Real>(phi, Sij, Sij, 2. * fourpiG * dx * dx / a);  // prepare nonlinear source for additional equations

#ifdef BENCHMARK
		ref2_time= MPI_Wtime();
#endif		
		plan_Sij.execute(FFT_FORWARD);  // go to k-space
#ifdef BENCHMARK
		fft_time += MPI_Wtime() - ref2_time;
		fft_count += 6;
#endif
		
		projectFTscalar(SijFT, scalarFT);  // construct chi by scalar projection (k-space)
		
		evolveFTvector(SijFT, BiFT, a * a * dtau_old);  // evlolve B using vector projection (k-space)

#ifdef BENCHMARK
		ref2_time= MPI_Wtime();
#endif		
		plan_chi.execute(FFT_BACKWARD);	 // go back to position space
#ifdef BENCHMARK
		fft_time += MPI_Wtime() - ref2_time;
		fft_count++;
#endif	
		chi.updateHalo();  // communicale halo values
		
		if (sim.gr_flag > 0)
		{
			for (x.first(); x.test(); x.next())  // update psi
				psi(x) = phi(x) - chi(x);

#ifdef BENCHMARK
			ref2_time= MPI_Wtime();
#endif				
			plan_Bi.execute(FFT_BACKWARD);  // go back to position space
#ifdef BENCHMARK
			fft_time += MPI_Wtime() - ref2_time;
			fft_count += 3;
#endif
			Bi.updateHalo();  // communicate halo values
		}
		else
		{
			for (x.first(); x.test(); x.next())  // Newton: update psi
				psi(x) = phi(x);
		}
		
		psi.updateHalo();  // communicate halo values
		
		// compute number of step subdivisions for particle updates
		numsteps = 1;
		for (i = 0; i < cosmo.num_ncdm; i++)
		{
			if (dtau * maxvel_ncdm[i] > dx * sim.movelimit)
				numsteps_ncdm[i] = (int) ceil(dtau * maxvel_ncdm[i] / dx / sim.movelimit);
			else numsteps_ncdm[i] = 1;
			
			if (numsteps < numsteps_ncdm[i]) numsteps = numsteps_ncdm[i];
		}
		if (numsteps > 1 && numsteps % 2 > 0) numsteps++;   // if >1, make it an even number
		
		for (i = 0; i < cosmo.num_ncdm; i++)
		{
			if (numsteps / numsteps_ncdm[i] <= 1) numsteps_ncdm[i] = numsteps;
			else if (numsteps_ncdm[i] > 1) numsteps_ncdm[i] = numsteps / 2;
		}
		
		if (cycle % 10 == 0)
		{
			COUT << " cycle " << cycle << ", time integration information: max |v| = " << maxvel << " (cdm Courant factor = " << maxvel * sim.Cf << "), time step / Hubble time = " << Hconf(a, fourpiG, cosmo) * dtau;
			
			for (i = 0; i < cosmo.num_ncdm; i++)
			{
				if (i == 0)
				{
					COUT << endl << " time step subdivision for ncdm species: ";
				}
				COUT << numsteps_ncdm[i] << " (max |v| = " << maxvel_ncdm[i] << ")";
				if (i < cosmo.num_ncdm-1)
				{
					COUT << ", ";
				}
			}
			
			COUT << endl;
		}
		
		for (j = 0; j < numsteps; j++) // particle update
		{
#ifdef BENCHMARK
			ref2_time = MPI_Wtime();
#endif
			f_params[0] = a;
			f_params[1] = a * a * sim.numpts;
			if (j == 0)
			{
				if (sim.gr_flag > 0)
					maxvel = pcls_cdm.updateVel(update_q, (dtau + dtau_old) / 2., update_cdm_fields, (1. / a < ic.z_relax + 1. ? 3 : 1), f_params);
				else
					maxvel = pcls_cdm.updateVel(update_q_Newton, (dtau + dtau_old) / 2., update_cdm_fields, 1, f_params);

#ifdef BENCHMARK
				update_q_count++;
#endif
			}
				
			for (i = 0; i < cosmo.num_ncdm; i++)
			{
				if (j % (numsteps / numsteps_ncdm[i]) == 0)
				{
					if (sim.gr_flag > 0)
						maxvel_ncdm[i] = pcls_ncdm[i].updateVel(update_q, (dtau + dtau_old) / 2. / numsteps_ncdm[i], update_ncdm_fields, (1. / a < ic.z_relax + 1. ? 3 : 2), f_params);
					else
						maxvel_ncdm[i] = pcls_ncdm[i].updateVel(update_q_Newton, (dtau + dtau_old) / 2. / numsteps_ncdm[i], update_ncdm_fields, 1, f_params);

#ifdef BENCHMARK
					update_q_count++;
#endif
				}
			}
#ifdef BENCHMARK
			update_q_time += MPI_Wtime() - ref2_time;
			ref2_time = MPI_Wtime();
#endif
			if (numsteps > 1 && j == numsteps / 2)
			{
				if (sim.gr_flag > 0)
					pcls_cdm.moveParticles(update_pos, dtau, update_cdm_fields, (1. / a < ic.z_relax + 1. ? 3 : 0), f_params);
				else
					pcls_cdm.moveParticles(update_pos_Newton, dtau, NULL, 0, f_params);

#ifdef BENCHMARK
				moveParts_count++;
#endif
			}
		
			for (i = 0; i < cosmo.num_ncdm; i++)
			{
				if (numsteps > 1 && ((numsteps_ncdm[i] == 1 && j == numsteps / 2) || (numsteps_ncdm[i] == numsteps / 2 && j % 2 > 0)))
				{
					if (sim.gr_flag > 0)
						pcls_ncdm[i].moveParticles(update_pos, dtau / numsteps_ncdm[i], update_ncdm_fields, (1. / a < ic.z_relax + 1. ? 3 : 2), f_params);
					else
						pcls_ncdm[i].moveParticles(update_pos_Newton, dtau / numsteps_ncdm[i], NULL, 0, f_params);

#ifdef BENCHMARK
					moveParts_count++;
#endif
				}	  
			}
#ifdef BENCHMARK
			moveParts_time += MPI_Wtime() - ref2_time;
#endif  
			rungekutta4bg(a, fourpiG, cosmo, 0.5 * dtau / numsteps);  // evolve background by half a time step
#ifdef BENCHMARK
			ref2_time = MPI_Wtime();
#endif
			f_params[0] = a;
			f_params[1] = a * a * sim.numpts;
			if (numsteps == 1)
			{
				if (sim.gr_flag > 0)
					pcls_cdm.moveParticles(update_pos, dtau, update_cdm_fields, (1. / a < ic.z_relax + 1. ? 3 : 0), f_params);
				else
					pcls_cdm.moveParticles(update_pos_Newton, dtau, NULL, 0, f_params);

#ifdef BENCHMARK
				moveParts_count++;
#endif
			}
				
			for (i = 0; i < cosmo.num_ncdm; i++)
			{
				if (numsteps_ncdm[i] == numsteps)
				{
					if (sim.gr_flag > 0)
						pcls_ncdm[i].moveParticles(update_pos, dtau / numsteps_ncdm[i], update_ncdm_fields, (1. / a < ic.z_relax + 1. ? 3 : 2), f_params);
					else
						pcls_ncdm[i].moveParticles(update_pos_Newton, dtau / numsteps_ncdm[i], NULL, 0, f_params);

#ifdef BENCHMARK
					moveParts_count++;
#endif
				}
			}
#ifdef BENCHMARK
			moveParts_time += MPI_Wtime() - ref2_time;
#endif
			rungekutta4bg(a, fourpiG, cosmo, 0.5 * dtau / numsteps);  // evolve background by half a time step
		}   // particle update done
		
		parallel.max<double>(maxvel);
		if (cosmo.num_ncdm > 0) parallel.max<double>(maxvel_ncdm, cosmo.num_ncdm);
		
		if (sim.gr_flag > 0)
		{
			maxvel /= sqrt(maxvel * maxvel + 1.0);
			for (i = 0; i < cosmo.num_ncdm; i++)
				maxvel_ncdm[i] /= sqrt(maxvel_ncdm[i] * maxvel_ncdm[i] + 1.0);
		}
		
		tau += dtau;
		
		if (tau_Lambda < 0. && (cosmo.Omega_m / a / a / a) < cosmo.Omega_Lambda)
		{
			tau_Lambda = tau;
			COUT << "matter-dark energy equality at z=" << ((1./a) - 1.) << endl;
		}
		
		dtau_old = dtau;
		
		if (sim.Cf * dx < sim.steplimit / Hconf(a, fourpiG, cosmo))
			dtau = sim.Cf * dx;
		else
			dtau = sim.steplimit / Hconf(a, fourpiG, cosmo);
		   
		cycle++;
		
#ifdef BENCHMARK
		gravity_solver_time += MPI_Wtime() - ref_time;
		cycle_time += MPI_Wtime()-cycle_start_time;
#endif
	}
	
	COUT << " simulation complete." << endl;
	
#ifdef BENCHMARK
	run_time = MPI_Wtime() - start_time;

	parallel.sum(run_time);
	parallel.sum(cycle_time);
	parallel.sum(projection_time);
	parallel.sum(snapshot_output_time);
	parallel.sum(spectra_output_time);
	parallel.sum(gravity_solver_time);
	parallel.sum(fft_time);
	parallel.sum(update_q_time);
	parallel.sum(moveParts_time);
	
	COUT << endl << "BENCHMARK" << endl;   
	COUT << "total execution time  : "<<hourMinSec(run_time) << endl;
	COUT << "total number of cycles: "<< cycle << endl;
	COUT << "time consumption breakdown:" << endl;
	COUT << "initialization   : "  << hourMinSec(initialization_time) << " ; " << 100. * initialization_time/run_time <<"%."<<endl;
	COUT << "main loop        : "  << hourMinSec(cycle_time) << " ; " << 100. * cycle_time/run_time <<"%."<<endl;
	
	COUT << "----------- main loop: components -----------"<<endl;
	COUT << "projections          : "<< hourMinSec(projection_time) << " ; " << 100. * projection_time/cycle_time <<"%."<<endl;
	COUT << "snapshot outputs     : "<< hourMinSec(snapshot_output_time) << " ; " << 100. * snapshot_output_time/cycle_time <<"%."<<endl;
	COUT << "power spectra outputs: "<< hourMinSec(spectra_output_time) << " ; " << 100. * spectra_output_time/cycle_time <<"%."<<endl;
	COUT << "gravity solver       : "<< hourMinSec(gravity_solver_time) << " ; " << 100. * gravity_solver_time/cycle_time <<"%."<<endl;
	
	COUT << "----------- gravity solver: components ------------"<<endl;
	COUT << "Fast Fourier Transforms (count: " << fft_count <<"): "<< hourMinSec(fft_time) << " ; " << 100. * fft_time/gravity_solver_time <<"%."<<endl;
	COUT << "update momenta (count: "<<update_q_count <<"): "<< hourMinSec(update_q_time) << " ; " << 100. * update_q_time/gravity_solver_time <<"%."<<endl;
	COUT << "move particles (count: "<< moveParts_count <<"): "<< hourMinSec(moveParts_time) << " ; " << 100. * moveParts_time/gravity_solver_time <<"%."<<endl;
#endif
	
	free(kbin);
	free(power);
	free(kscatter);
	free(pscatter);
	free(occupation);

#ifdef EXTERNAL_IO	
		ioserver.stop();
	}
#endif
}
Example #13
0
static inline void field(double & f, const Field & v, double def = 0.0)
{
	f = v.empty() ? def : atof(v.c_str());
}
Example #14
0
static inline void field(float & f, const Field & v, float def = 0.0f)
{
	f = v.empty() ? def : atof(v.c_str());
}
Example #15
0
int main (int argc, char **argv)
{
	// ofstream report;

	bool pass = true;

	static size_t m = 4;
	static size_t n = 20;
	static size_t nnz = 0;
	static integer q = 65521U;
	q = 101;

	static Argument args[] = {
		{ 'm', "-m M", "Set row dimension of test matrix to M.", TYPE_INT,     &m },
		{ 'n', "-n N", "Set col dimension of test matrix to N.", TYPE_INT,     &n },
		{ 'z', "-n NNZ", "Set number of nonzero entries in test matrix.", TYPE_INT,     &nnz },
		{ 'q', "-q Q", "Operate over the \"field\" GF(Q) [1].", TYPE_INTEGER, &q },
		END_OF_ARGUMENTS
	};

	parseArguments (argc, argv, args);

	if (nnz == 0) nnz = m*n/10;

	srand ((unsigned)time (NULL));

	commentator().start("TriplesBB black box test suite", "triplesbb");

	//Field
	typedef Givaro::Modular<double> Field;
	typedef Field::Element Element;
	Field F (q);
	MatrixDomain<Field> MD(F);
	typedef MatrixDomain<Field>::OwnMatrix OwnMatrix;
	//Vectors
	VectorDomain<Field> VD(F);
	BlasVector<Field> x(F,n), y(F,m), z(F,m);
	for (size_t i = 0; i < n; ++i) F.init(x[i], i+1);

	// TriplesBB<Field> A(F, m, n);
	SparseMatrix<Field,SparseMatrixFormat::TPL> A(F, m, n);
	randBuild(A, nnz);
	pass = pass && testBlackbox(A);
	// just see if it compiles
	size_t b = 10;
	OwnMatrix X(F,n,b), Y(F,m,b), Z(F,b,m), W(F,b,n);
	X.random(); Z.random();
	A.applyLeft(Y, X);
	A.applyRight(W, Z);

	// standard constructor
	// TriplesBB<Field> B(F, m, n);
	SparseMatrix<Field,SparseMatrixFormat::TPL> B(F, m, n);
	bidiag(B);
	pass = pass && testBlackbox(B);
	B.apply(y, x);
	// default cstor plus init
	// TriplesBB<Field> C(F);
	SparseMatrix<Field,SparseMatrixFormat::TPL> C(F);
      	C.init(F, m, n);
	bidiag(C);
	pass = pass && testBlackbox(C);
	// check B == C
	C.apply(z, x);
	if (not VD.areEqual(y, z)) {
		pass = false;
		LinBox::commentator().report() << "fail: cstor and init disagree" << std::endl;
	}
	// copy construction
	// TriplesBB<Field> D(B);
	SparseMatrix<Field,SparseMatrixFormat::TPL> D(B);
	pass = pass && testBlackbox(D);
	// check B == D
	D.apply(z, x);
	if (not VD.areEqual(y, z)) {
		pass = false;
		LinBox::commentator().report() << "copy cstor failure" << std::endl;
	}

	// check that it's deep copy
	Element a;
	B.getEntry(a,0,0);
	F.addin(a, F.one);
	D.setEntry(0,0,a);
	D.apply(z, x);
	if (VD.areEqual(y, z)) {
		pass = false;
		LinBox::commentator().report() << "fail changed copy cstor and original agree" << std::endl;
		VD.write(commentator().report() << "y ", y) << std::endl;
		VD.write(commentator().report() << "z ", z) << std::endl;
	}

	commentator().stop("TriplesBB black box test suite");
	return pass ? 0 : -1;
}
Example #16
0
void buildVillage(Players_Character player, int* point, Field& f) {
  if (f.isNode(point) && f.isInArea(point)) {
    Node n(point);
    f.appendNode(player, &n);
  }
}
Example #17
0
static void getFieldTypeName(Field& f, std::string& name)
{
	name = getFieldInnerTypeName(f);
	if(f.isArray())
		name = "List<" + name + ">";
}
Example #18
0
TEST(Field, construction)
{
	Field field;
	EXPECT_EQ(sf::Vector2i(NUM_START_TILE % TILE_NUM_VER, NUM_START_TILE / TILE_NUM_VER), field.getStartTile()->getPosition());
	EXPECT_FALSE(field.getTile(NUM_START_TILE)->isPolluted());
	EXPECT_EQ(sf::Vector2i(NUM_END_TILE % TILE_NUM_VER, NUM_END_TILE / TILE_NUM_VER), field.getEndTile()->getPosition());
	EXPECT_FALSE(field.getTile(NUM_END_TILE)->isPolluted());

	std::vector<shared_ptr<Tile>> neighborTiles = field.getTile(sf::Vector2i(TILE_NUM_VER - 1, TILE_NUM_HOR - 1))->getNeighbor(1);
	EXPECT_EQ(4, neighborTiles.capacity());

	neighborTiles = field.getTile(sf::Vector2i(TILE_NUM_VER - 1, TILE_NUM_HOR - 1))->getNeighbor(1);
	EXPECT_EQ(4, neighborTiles.capacity());
	neighborTiles = field.getTile(sf::Vector2i(0, TILE_NUM_HOR - 1))->getNeighbor(1);
	EXPECT_EQ(4, neighborTiles.capacity());
	neighborTiles = field.getTile(sf::Vector2i(TILE_NUM_VER - 1, 0))->getNeighbor(1);
	EXPECT_EQ(4, neighborTiles.capacity());
	neighborTiles = field.getTile(sf::Vector2i(0, 8))->getNeighbor(1);
	EXPECT_EQ(6, neighborTiles.capacity());
	neighborTiles = field.getTile(sf::Vector2i(TILE_NUM_VER - 1, 5))->getNeighbor(1);
	EXPECT_EQ(6, neighborTiles.capacity());
	neighborTiles = field.getTile(sf::Vector2i(3, TILE_NUM_HOR - 1))->getNeighbor(1);
	EXPECT_EQ(6, neighborTiles.capacity());
	neighborTiles = field.getTile(sf::Vector2i(6, 0))->getNeighbor(1);
	EXPECT_EQ(6, neighborTiles.capacity());
	neighborTiles = field.getTile(sf::Vector2i(5, 8))->getNeighbor(1);
	EXPECT_EQ(9, neighborTiles.capacity());
	neighborTiles = field.getTile(sf::Vector2i(7,  TILE_NUM_HOR - 1))->getNeighbor(1);
	EXPECT_EQ(6, neighborTiles.capacity());
}
    forAll (procMeshes_, procI)
    {
        const GeometricField<Type, fvPatchField, volMesh>& procField =
            procFields[procI];

        // Set the cell values in the reconstructed field
        internalField.rmap
        (
            procField.internalField(),
            cellProcAddressing_[procI]
        );

        // Set the boundary patch values in the reconstructed field
        forAll (boundaryProcAddressing_[procI], patchI)
        {
            // Get patch index of the original patch
            const label curBPatch = boundaryProcAddressing_[procI][patchI];

            // Get addressing slice for this patch
            const labelList::subList cp =
                procMeshes_[procI].boundary()[patchI].patchSlice
                (
                    faceProcAddressing_[procI]
                );

            // check if the boundary patch is not a processor patch
            if (curBPatch >= 0)
            {
                // Regular patch. Fast looping

                if (!patchFields(curBPatch))
                {
                    patchFields.set
                    (
                        curBPatch,
                        fvPatchField<Type>::New
                        (
                            procField.boundaryField()[patchI],
                            mesh_.boundary()[curBPatch],
                            DimensionedField<Type, volMesh>::null(),
                            fvPatchFieldReconstructor
                            (
                                mesh_.boundary()[curBPatch].size(),
                                procField.boundaryField()[patchI].size()
                            )
                        )
                    );
                }

                const label curPatchStart =
                    mesh_.boundaryMesh()[curBPatch].start();

                labelList reverseAddressing(cp.size());

                forAll (cp, faceI)
                {
                    // Subtract one to take into account offsets for
                    // face direction.
                    reverseAddressing[faceI] = cp[faceI] - 1 - curPatchStart;
                }

                patchFields[curBPatch].rmap
                (
                    procField.boundaryField()[patchI],
                    reverseAddressing
                );
            }
            else
            {
Example #20
0
void PoissonSolver::linearStencil(std::vector<int> & Indices,
                                  std::vector<double> & Values,
                                  double & rhs,
                                  size_t & NumEntries,
                                  const Field<bool, DIM, Mesh_t, Vert> & isInside,
                                  const size_t & gid)
{
    const double EW = -1 / (_hr[0]*_hr[0]);
    const double NS = -1 / (_hr[1]*_hr[1]);

    const int idx = gid % _Nx;
    const int idy = gid / _Nx;
    const NDIndex<DIM> elem(Index(idx, idx), Index(idy, idy));

    if (isInside.localElement(elem)) {
        NumEntries = 5;

        Values[0] = NS;
        Indices[0] = gid - _Nx;
        Values[1] = EW;
        Indices[1] = gid - 1;
        Values[2] = -2 * (EW + NS);
        Indices[2] = gid;
        Values[3] = EW;
        Indices[3] = gid + 1;
        Values[4] = NS;
        Indices[4] = gid + _Nx;

        return;
    }

    const std::vector<int> & localToBCellNr = _bend.getInverseMapDualGrid();
    const int & localID = localToBCellNr[_bend.getLocalID(elem)];

    if (localID == -1) {
        NumEntries = 1;
        Values[0] = 1;
        Indices[0] = gid;

        NDIndex<DIM> elemmy(elem[0], elem[1] - 1);
        int localIDmy = localToBCellNr[_bend.getLocalID(elemmy)];
        if (localIDmy != -1 && _boundaryCells[localIDmy].lambda_m(1) > SPACE_EPS) {
            const BoundaryCell & bc = _boundaryCells[localIDmy];
            const double & s = bc.lambda_m(1);

            Values[NumEntries] = (1/s - 1);
            Indices[NumEntries] = gid - _Nx;

            dbg << gid << "    "
                << gid - _Nx << "    "
                << Values[NumEntries] << std::endl;

            Values[0] = NumEntries;
            NumEntries += 1;
        }
        NDIndex<DIM> elemmx(elem[0] - 1, elem[1]);
        int localIDmx = localToBCellNr[_bend.getLocalID(elemmx)];
        if (localIDmx != -1 && _boundaryCells[localIDmx].lambda_m(0) > SPACE_EPS) {
            const BoundaryCell & bc = _boundaryCells[localIDmx];
            const double & s = bc.lambda_m(0);

            Values[NumEntries] = (1/s - 1);
            Indices[NumEntries] = gid - 1;

            dbg << gid << "    "
                << gid - 1 << "    "
                << Values[NumEntries] << std::endl;

            Values[0] = NumEntries;
            NumEntries += 1;
        }

        rhs = 0.0;
        return;
    }

    const BoundaryCell & bc = _boundaryCells[localID];
    if (bc.lambda_m[0] > 1 - SPACE_EPS ||
        bc.lambda_m[1] > 1 - SPACE_EPS) {

        NumEntries = 5;

        Values[0] = NS;
        Indices[0] = gid - _Nx;
        Values[1] = EW;
        Indices[1] = gid - 1;
        Values[2] = -2 * (EW + NS);
        Indices[2] = gid;
        Values[3] = EW;
        Indices[3] = gid + 1;
        Values[4] = NS;
        Indices[4] = gid + _Nx;

    } else {
        NumEntries = 1;
        Values[0] = 1;
        Indices[0] = gid;

        if (bc.lambda_m(0) > SPACE_EPS) {
            const double & s = bc.lambda_m(0);

            Values[NumEntries] = (1/s - 1);
            Indices[NumEntries] = gid + 1;

            dbg << gid << "    "
                << gid + 1 << "    "
                << Values[NumEntries] << std::endl;

            Values[0] = NumEntries;
            NumEntries += 1;
        }

        if (bc.lambda_m(1) > SPACE_EPS) {
            const double & s = bc.lambda_m(1);

            Values[NumEntries] = (1/s - 1);
            Indices[NumEntries] = gid + _Nx;

            dbg << gid << "    "
                << gid + _Nx << "    "
                << Values[NumEntries] << std::endl;

            Values[0] = NumEntries;
            NumEntries += 1;
        }

        rhs = 0.0;
    }

    return;
}
Example #21
0
Foam::lduMatrix::solverPerformance Foam::fvMatrix<Type>::solve
(
    const dictionary& solverControls
)
{
    if (debug)
    {
        Info<< "fvMatrix<Type>::solve(const dictionary&) : "
               "solving fvMatrix<Type>"
            << endl;
    }

    lduSolverPerformance solverPerfVec
    (
        "fvMatrix<Type>::solve",
        psi_.name()
    );

    scalarField saveDiag = diag();

    Field<Type> source = source_;

    // At this point include the boundary source from the coupled boundaries.
    // This is corrected for the implicit part by updateMatrixInterfaces within
    // the component loop.
    addBoundarySource(source);

    typename Type::labelType validComponents
    (
        pow
        (
            psi_.mesh().solutionD(),
            pTraits<typename powProduct<Vector<label>, Type::rank>::type>::zero
        )
    );

    // Make a copy of interfaces: no longer a reference
    // HJ, 20/Nov/2007
    lduInterfaceFieldPtrsList interfaces = psi_.boundaryField().interfaces();

    for (direction cmpt = 0; cmpt < Type::nComponents; cmpt++)
    {
        if (validComponents[cmpt] == -1) continue;

        // Copy field and source

        scalarField psiCmpt = psi_.internalField().component(cmpt);
        addBoundaryDiag(diag(), cmpt);

        scalarField sourceCmpt = source.component(cmpt);

        FieldField<Field, scalar> bouCoeffsCmpt
        (
            boundaryCoeffs_.component(cmpt)
        );

        FieldField<Field, scalar> intCoeffsCmpt
        (
            internalCoeffs_.component(cmpt)
        );

        // Use the initMatrixInterfaces and updateMatrixInterfaces to correct
        // bouCoeffsCmpt for the explicit part of the coupled boundary
        // conditions
        initMatrixInterfaces
        (
            bouCoeffsCmpt,
            interfaces,
            psiCmpt,
            sourceCmpt,
            cmpt
        );

        updateMatrixInterfaces
        (
            bouCoeffsCmpt,
            interfaces,
            psiCmpt,
            sourceCmpt,
            cmpt
        );

        lduMatrix::solverPerformance solverPerf;

        // Solver call
        solverPerf = lduMatrix::solver::New
        (
            psi_.name() + pTraits<Type>::componentNames[cmpt],
            *this,
            bouCoeffsCmpt,
            intCoeffsCmpt,
            interfaces,
            solverControls
        )->solve(psiCmpt, sourceCmpt, cmpt);

        solverPerf.print();

        if
        (
            solverPerf.initialResidual() > solverPerfVec.initialResidual()
         && !solverPerf.singular()
        )
        {
            solverPerfVec = solverPerf;
        }

        psi_.internalField().replace(cmpt, psiCmpt);
        diag() = saveDiag;
    }

    psi_.correctBoundaryConditions();

    return solverPerfVec;
}
Example #22
0
void PoissonSolver::cutoffStencil(std::vector<int> & Indices,
                                  std::vector<double> & Values,
                                  double & rhs,
                                  size_t & NumEntries,
                                  const Field<bool, DIM, Mesh_t, Cell> & isInside,
                                  const size_t & gid)
{
    const double EW = -1 / (_hr[0]*_hr[0]);
    const double NS = -1 / (_hr[1]*_hr[1]);

    const int idx = gid % _Nx;
    const int idy = gid / _Nx;
    const NDIndex<DIM> elem(Index(idx, idx), Index(idy, idy));
    const NDIndex<DIM> elemmx(elem[0] - 1, elem[1]);
    const NDIndex<DIM> elemmy(elem[0], elem[1] - 1);
    const NDIndex<DIM> elempx(elem[0] + 1, elem[1]);
    const NDIndex<DIM> elempy(elem[0], elem[1] + 1);

    const std::vector<int> & localToBCellNr = _bend.getInverseMap();
    const int & localID = localToBCellNr[_bend.getLocalID(elem)];
    const int & localIDmx = localToBCellNr[_bend.getLocalID(elemmx)];
    const int & localIDmy = localToBCellNr[_bend.getLocalID(elemmy)];
    const int & localIDpx = localToBCellNr[_bend.getLocalID(elempx)];
    const int & localIDpy = localToBCellNr[_bend.getLocalID(elempy)];

    long maxX = _bend.getLengthStraightSection();

    if (idx < maxX &&
        (isInside.localElement(elem) ||
         (localID > -1 &&
          _boundaryCells[localID].area_m > 0.5))) {

        NumEntries = 0;

        if (isInside.localElement(elemmy) ||
            (localIDmy > -1 &&
             _boundaryCells[localIDmy].area_m > 0.5)) {

            Indices[NumEntries] = gid - _Nx;
            Values[NumEntries] = NS;

            NumEntries ++;
        }

        if (isInside.localElement(elemmx) ||
            (localIDmx > -1 &&
             _boundaryCells[localIDmx].area_m > 0.5)) {

            Indices[NumEntries] = gid - 1;
            Values[NumEntries] = EW;

            NumEntries ++;
        }

        if (isInside.localElement(elempx) ||
            (localIDpx > -1 &&
             _boundaryCells[localIDpx].area_m > 0.5)) {

            Indices[NumEntries] = gid + 1;
            Values[NumEntries] = EW;

            NumEntries ++;
        }

        if (isInside.localElement(elempy) ||
            (localIDpy > -1 &&
             _boundaryCells[localIDpy].area_m > 0.5)) {

            Indices[NumEntries] = gid + _Nx;
            Values[NumEntries] = NS;

            NumEntries ++;
        }

        Indices[NumEntries] = gid;
        Values[NumEntries] = -2 * (EW + NS);

        NumEntries ++;

        return;
    }

    NumEntries = 1;
    Indices[0] = gid;
    Values[0] = 1;
    rhs = 0;

    return;
}
Example #23
0
typename Foam::SolverPerformance<Type>
Foam::PCICG<Type, DType, LUType>::solve(Field<Type>& psi) const
{
    word preconditionerName(this->controlDict_.lookup("preconditioner"));

    // --- Setup class containing solver performance data
    SolverPerformance<Type> solverPerf
    (
        preconditionerName + typeName,
        this->fieldName_
    );

    label nCells = psi.size();

    Type* __restrict__ psiPtr = psi.begin();

    Field<Type> pA(nCells);
    Type* __restrict__ pAPtr = pA.begin();

    Field<Type> wA(nCells);
    Type* __restrict__ wAPtr = wA.begin();

    Type wArA = solverPerf.great_*pTraits<Type>::one;
    Type wArAold = wArA;

    // --- Calculate A.psi
    this->matrix_.Amul(wA, psi);

    // --- Calculate initial residual field
    Field<Type> rA(this->matrix_.source() - wA);
    Type* __restrict__ rAPtr = rA.begin();

    // --- Calculate normalisation factor
    Type normFactor = this->normFactor(psi, wA, pA);

    if (LduMatrix<Type, DType, LUType>::debug >= 2)
    {
        Info<< "   Normalisation factor = " << normFactor << endl;
    }

    // --- Calculate normalised residual norm
    solverPerf.initialResidual() = cmptDivide(gSumCmptMag(rA), normFactor);
    solverPerf.finalResidual() = solverPerf.initialResidual();

    // --- Check convergence, solve if not converged
    if
    (
        this->minIter_ > 0
     || !solverPerf.checkConvergence(this->tolerance_, this->relTol_)
    )
    {
        // --- Select and construct the preconditioner
        autoPtr<typename LduMatrix<Type, DType, LUType>::preconditioner>
        preconPtr = LduMatrix<Type, DType, LUType>::preconditioner::New
        (
            *this,
            this->controlDict_
        );

        // --- Solver iteration
        do
        {
            // --- Store previous wArA
            wArAold = wArA;

            // --- Precondition residual
            preconPtr->precondition(wA, rA);

            // --- Update search directions:
            wArA = gSumCmptProd(wA, rA);

            if (solverPerf.nIterations() == 0)
            {
                for (label cell=0; cell<nCells; cell++)
                {
                    pAPtr[cell] = wAPtr[cell];
                }
            }
            else
            {
                Type beta = cmptDivide
                (
                    wArA,
                    stabilise(wArAold, solverPerf.vsmall_)
                );

                for (label cell=0; cell<nCells; cell++)
                {
                    pAPtr[cell] = wAPtr[cell] + cmptMultiply(beta, pAPtr[cell]);
                }
            }


            // --- Update preconditioned residual
            this->matrix_.Amul(wA, pA);

            Type wApA = gSumCmptProd(wA, pA);


            // --- Test for singularity
            if
            (
                solverPerf.checkSingularity
                (
                    cmptDivide(cmptMag(wApA), normFactor)
                )
            )
            {
                break;
            }


            // --- Update solution and residual:

            Type alpha = cmptDivide
            (
                wArA,
                stabilise(wApA, solverPerf.vsmall_)
            );

            for (label cell=0; cell<nCells; cell++)
            {
                psiPtr[cell] += cmptMultiply(alpha, pAPtr[cell]);
                rAPtr[cell] -= cmptMultiply(alpha, wAPtr[cell]);
            }

            solverPerf.finalResidual() =
                cmptDivide(gSumCmptMag(rA), normFactor);

        } while
        (
            (
                solverPerf.nIterations()++ < this->maxIter_
            && !solverPerf.checkConvergence(this->tolerance_, this->relTol_)
            )
         || solverPerf.nIterations() < this->minIter_
        );
    }

    return solverPerf;
}
 virtual int onNext(const Field &f)
 {
     EXPECT_EQ(f.type(), Field::COMPOSITE);
     EXPECT_EQ(f.fieldName(), "");
     EXPECT_EQ(f.compositeName(), "messageHeader");
     EXPECT_EQ(f.schemaId(), Field::INVALID_ID);
     EXPECT_EQ(f.numEncodings(), 4);
     EXPECT_EQ(f.encodingName(0), "blockLength");
     EXPECT_EQ(f.encodingName(1), "templateId");
     EXPECT_EQ(f.encodingName(2), "version");
     EXPECT_EQ(f.encodingName(3), "reserved");
     EXPECT_EQ(f.primitiveType(0), Ir::UINT16);
     EXPECT_EQ(f.primitiveType(1), Ir::UINT16);
     EXPECT_EQ(f.primitiveType(2), Ir::UINT8);
     EXPECT_EQ(f.primitiveType(3), Ir::UINT8);
     EXPECT_EQ(f.getUInt(0), BLOCKLENGTH);
     EXPECT_EQ(f.getUInt(1), TEMPLATE_ID);
     EXPECT_EQ(f.getUInt(2), VERSION);
     EXPECT_EQ(f.getUInt(3), 0u);
     numFieldsSeen_++;
     return 0;
 };
Example #25
0
void Node::cloneFieldValue ( Field& _from, Field& _to, bool deepCopy, DeepCopyMap& deepCopyMap ) {
  // Only copy INPUT_OUTPUT and INITIALIZE_ONLY
  if ( _from.getAccessType() == Field::INPUT_OUTPUT || _from.getAccessType() == Field::INITIALIZE_ONLY ) {

    // MField types
    if( MFieldClass *mfield_from = dynamic_cast< MFieldClass * >( &_from ) ) {
            
      // MFNode
      if( MFNode *mfnode_from = dynamic_cast< MFNode * >( &_from ) ) {
        if ( MFNode *mfnode_to = dynamic_cast< MFNode * >( &_to ) ) {
          NodeVector src= mfnode_from->getValue();
          for ( size_t j= 0; j < src.size(); ++j ) {
            src.set ( j, getClonedInstance ( src[j], deepCopy, deepCopyMap ) );
          }
          mfnode_to->setValue ( src );
        }

        // MFString
      } else if ( MFString *mfstring_from = dynamic_cast< MFString * > ( &_from ) ) {
        // MFString does not work with getValueAsVoidPtr. Do special case or fix getValueAsVoidPtr.
        if ( MFString *mfstring_to = dynamic_cast< MFString * >( &_to ) ) {
          if ( !mfstring_from->getValueAsString().empty() ){
            // avoid setting value when not actaully needed
            mfstring_to->setValue ( mfstring_from->getValue ( ) );
          }
        }

        // Generic MField
      } else {
        if ( MFieldClass *mfield_to = dynamic_cast< MFieldClass * >( &_to ) ) {
          unsigned int data_size = mfield_from->valueTypeSize() * mfield_from->size();
          unsigned int nr_elements;
          unsigned char* data = new unsigned char[ data_size ];
          int result = mfield_from->getValueAsVoidPtr( data, nr_elements, data_size );
          if ( result != -1 ) {
            mfield_to->setValueFromVoidPtr ( (const void*) data, nr_elements, data_size );
          }
          delete [] data;
        }
      }

      // SField types
    } else if( SFieldClass *sfield_from = dynamic_cast< SFieldClass * >( &_from ) ) {
      
      // SFString
      if( SFString *sfstring_from = dynamic_cast< SFString * > ( &_from ) ) {
        // the getValueAsVoidPtr function does not work well with
        // SFString fields so do a special case for that type.
        if ( SFString *sfstring_to = dynamic_cast< SFString * >( &_to ) ) {
          if ( !sfstring_from->getValue().empty() ){
            // avoid setValue for sfstring_to when not really needed
            sfstring_to->setValue ( sfstring_from->getValue ( ) );
          }
        }
        // Generic SField
      } else {
        if ( SFieldClass *sfield_to = dynamic_cast< SFieldClass * >( &_to ) ) {
          unsigned int data_size = sfield_from->valueTypeSize();
          unsigned char* data = new unsigned char[ data_size ];
          data_size = sfield_from->getValueAsVoidPtr( data, data_size );
          if ( data_size != -1 ) {
            sfield_to->setValueFromVoidPtr ( (const void *)data, data_size );
          }
          delete [] data;
        }
      }

      // SFNode
    } else if( SFNode *sfnode_from = dynamic_cast< SFNode * >( &_from ) ) {
      if ( SFNode *sfnode_to = dynamic_cast< SFNode * >( &_to ) ) {
        Node* n= getClonedInstance ( sfnode_from->getValue(), deepCopy, deepCopyMap );
        sfnode_to->setValue ( n );
      }
    }
  }
}
Example #26
0
bool check_ftrsm (const Field &F, size_t m, size_t n, const typename Field::Element &alpha, FFLAS::FFLAS_SIDE side, FFLAS::FFLAS_UPLO uplo, FFLAS::FFLAS_TRANSPOSE trans, FFLAS::FFLAS_DIAG diag, RandIter& Rand){

	typedef typename Field::Element Element;
	Element * A, *B, *B2, *C, tmp;
	size_t k = (side==FFLAS::FflasLeft?m:n);
	size_t lda,ldb,ldc;
	lda=k+13;
	ldb=n+14;
	ldc=n+15;
	A  = FFLAS::fflas_new(F,k,lda);
	B  = FFLAS::fflas_new(F,m,ldb);
	B2 = FFLAS::fflas_new(F,m,ldb);
	C  = FFLAS::fflas_new(F,m,ldc);

	RandomTriangularMatrix (F, k, k, uplo, diag, true, A, lda, Rand);
	RandomMatrix (F, m, n, B, ldb, Rand);
	FFLAS::fassign (F, m, n, B, ldb, B2, ldb);

	string ss=string((uplo == FFLAS::FflasLower)?"Lower_":"Upper_")+string((side == FFLAS::FflasLeft)?"Left_":"Right_")+string((trans == FFLAS::FflasTrans)?"Trans_":"NoTrans_")+string((diag == FFLAS::FflasUnit)?"Unit":"NonUnit");

	cout<<std::left<<"Checking FTRSM_";
	cout.fill('.');
	cout.width(35);
	cout<<ss;


	FFLAS::Timer t; t.clear();
	double time=0.0;
	t.clear();
	t.start();
	FFLAS::ftrsm (F, side, uplo, trans, diag, m, n, alpha, A, lda, B, ldb);
	t.stop();
	time+=t.usertime();

	Element invalpha;
	F.init(invalpha);
	F.inv(invalpha, alpha);

	//FFLAS::ftrmm (F, side, uplo, trans, diag, m, n, invalpha, A, k, B, n);

	if (side == FFLAS::FflasLeft)
		FFLAS::fgemm(F, trans, FFLAS::FflasNoTrans, m, n, m, invalpha, A, lda, B, ldb, F.zero, C, ldc);
	else
		FFLAS::fgemm(F, FFLAS::FflasNoTrans, trans, m, n, n, invalpha, B, ldb, A, lda, F.zero, C, ldc);

	bool ok = true;
	if (FFLAS::fequal (F, m, n, B2, ldb, C, ldc)){
	    //cout << "\033[1;32mPASSED\033[0m ("<<time<<")"<<endl;
		cout << "PASSED ("<<time<<")"<<endl;
		//cerr<<"PASSED ("<<time<<")"<<endl;
	} else{
	    //cout << "\033[1;31mFAILED\033[0m ("<<time<<")"<<endl;
		cout << "FAILED ("<<time<<")"<<endl;
		ok=false;
		//cerr<<"FAILED ("<<time<<")"<<endl;
	}

	F.mulin(invalpha,alpha);
	if (!F.isOne(invalpha)){
		cerr<<"invalpha is wrong !!!"<<endl;;
	}

	FFLAS::fflas_delete(A);
	FFLAS::fflas_delete(B);
	FFLAS::fflas_delete(B2);
	FFLAS::fflas_delete(C);
	return ok;
}
Example #27
0
	int destroyElementsConditional(Field& conditionalField)
	{
		return Cmiss_mesh_destroy_elements_conditional(id,
			conditionalField.getId());
	}
Example #28
0
void Node::outputXMLField(std::ostream& ps, Field *field, int indentLevel, bool isSingleLine)  const
{
	char *indentString = getIndentLevelString(indentLevel+1);
	const char *fieldName = field->getName();
	char *spaceString = getSpaceString(StringLength(fieldName)+2);

	if (hasOutputXMLField(field) == false) {
		delete [] indentString;
		delete [] spaceString;
		return;
	}

	if (isSingleLine == true)
		ps << " ";
	else
		ps << std::endl;
	
	if (field->isSField() == true) {
		if (isSingleLine == false)
			ps << indentString;
    if (field->toXMLString ())
      ps <<  fieldName << "=\"" << field->toXMLString() << "\"";
		delete [] indentString;
		delete [] spaceString;
		return;
	}
		
	if (field->isMField() == true) {
		MField *mfield = (MField *)field;
		int fieldSize = mfield->getSize();

		if (fieldSize == 0) {
			ps << indentString << fieldName << "=\"" << "\"";
			delete [] indentString;
			delete [] spaceString;
			return;
		}
			
		if (fieldSize == 1) {
			Field *eleField	= (Field*)mfield->getObject(0);
			string eleString = eleField->toXMLString();
      ps << indentString << fieldName << "=\"" << eleString.c_str() << "\"";
			delete [] indentString;
			delete [] spaceString;
			return;
		}

		for (int n=0; n<fieldSize; n++) {
			if (n==0)
				ps << indentString << fieldName << "=\"";
			ps << indentString << spaceString;
					
			Field *eleField	= (Field*)mfield->getObject(n);
			string eleString = eleField->toXMLString();
				
			ps << eleString;
				
			if (n < (fieldSize-1)) {
				ps << std::endl;
				/*
				if (mfield->isSingleValueMField() == true)
					ps << std::endl;
				else
					ps << "," << std::endl;
				*/
			}
			else
				ps << "\"";
		}
		delete [] indentString;
		delete [] spaceString;
		return;
	}

	delete []indentString;
	delete []spaceString;
}
Example #29
0
void GrbSource::get(Field& x) {
  int n = d_so.getNumber();
  x.assign(n);
  d_eoi = d_so.eof();
};
int AI::thinkWrapperEX(Field self, Field enemy)
{
	Time.reset();
	stop = false;
	calls_count = 0;
	int timeLimit = 999999;

	// 静かな局面になるまで局面を進める
	int my_remain_time = enemy.generateStaticState(self);

	// enemyが死んでいる局面の場合は-1が返ってくる
	if (my_remain_time == -1)
	{
		if (enemy.isDeath())
		{
			operate_.clear();

			// その時は探索は行わず、ずっと回転し続けることにする(煽りではない)
			for (int i = 0; i < 1000; i++)
			{
				if (i % 7 == 0)
					operate_.push(R_ROTATE);
				else
					operate_.push(0);
			}
			return 0;
		}
	}

	// 進めたことによりエラーが発生しないかどうか。
	assert(self.examine());
	assert(enemy.examine());

	// 探索用に小さなサイズのフィールドにする
	LightField s(self);
	LightField e(enemy);

	assert(s.chainMax() == 0 && e.chainMax() == 0);
	assert(s.examine());
	assert(e.examine());

	ChainsList* c1 = new ChainsList(100);
	ChainsList* c2 = new ChainsList(100);

	s.setChains(c1);
	e.setChains(c2);

	// 世代を進める
	TT.newSearch();

	Score alpha = -SCORE_INFINITE;	// α:下限値
	Score beta = SCORE_INFINITE;	// β:上限値
	Score delta = alpha;
	Score score = SCORE_ZERO;
	continue_self_num_ = 0;

	Move best_move;

	Move mlist[22];
	int mcount = s.generateMoves(mlist);

	// 死んでいる局面ではないはず
	assert(mcount > 0);

	root_moves.clear();

	for (int i = 0; i < mcount; ++i)
	{
		root_moves.push_back(Search::RootMove(mlist[i]));
		root_moves[i].player.push_back(self.player());
	}

	// 反復深化
	for (Depth d = ONE_PLY; d <= depth_max_; ++d)
	{
		if (stop)
			break;

		MyOutputDebugString("depth = %d, stop = %d\n", d, stop);

		// 前回のiterationでの指し手の点数をすべてコピー
		for (int i = 0; i < root_moves.size(); ++i)
			root_moves[i].previous_score = root_moves[i].score;

#if 0
		// aspiration search
		// alpha betaをある程度絞ることで、探索効率を上げる。
		if (3 <= depth_max_ && abs(root_moves[0].previous_score) < SCORE_INFINITE)
		{
			delta = static_cast<Score>(5);
			alpha = static_cast<Score>(root_moves[0].previous_score) - delta;
			beta = static_cast<Score>(root_moves[0].previous_score) + delta;
		}
		else
#endif
		{
			alpha = -SCORE_INFINITE;
			beta = SCORE_INFINITE;
		}

		// aspiration search のwindow幅をはじめは小さい値にして探索し、
		// fail high/lowになったなら、今度はwindow幅を広げて再探索を行う。
		while (true)
		{
			// 探索開始
			score = search<ROOT>(alpha, beta, s, e, d, my_remain_time);

			// 先頭が最善手になるようにソート
			insertionSort(root_moves.begin(), root_moves.end());

			// fail high / lowが起きなかった場合はループを抜ける。
			if (alpha < score && score < beta)
				break;

			// fail low/highが起きた場合、aspiration窓を増加させ再探索し、
			// さもなくばループを抜ける。
			if (abs(score) >= Score(10000))
			{
				// 勝ちか負けだと判定したら、最大の幅で探索を試してみる。
				alpha = -SCORE_INFINITE;
				beta = SCORE_INFINITE;
			}
			else if (beta <= score)
			{
				beta += delta;
				delta += delta / 2;
			}
			else
			{
				alpha -= delta;
				delta += delta / 2;
			}

			if (stop)
				break;
		}

		best_move = stop ? best_move : best_[d];

		MyOutputDebugString("score = %d, depth = %d, best = %s", score, depth_max_, best_move.toString(self, 0));

		int s_field_ply = 0;
		int e_field_ply = 0;

		// pv表示
		for (int size = 0; size < root_moves[0].pv.size() - 1; size++)
		{
			LightField* now_player = root_moves[0].player[size] == self.player() ? &self : &enemy;

			int now_field_ply;

			if (now_player == &self)
				now_field_ply = s_field_ply++;
			else
				now_field_ply = e_field_ply++;

			MyOutputDebugString("%s%s,",
				root_moves[0].player[size] == PLAYER1 ? "P1:" : "P2:",
				root_moves[0].pv[size].toString(*now_player, now_field_ply).c_str());
		}

		MyOutputDebugString("\n");
	}

	MyOutputDebugString("\n");

	// 探索した結果得られた手を実際に配置できるかどうか。
	assert(self.isEmpty(best_move.psq()) && self.isEmpty(best_move.csq()));

	// best_moveを操作に変換
	operate_.generate(best_move, self);

	delete c1;
	delete c2;

	return score;
}