Exemple #1
0
ImageBuf *
SMF::getGrass()
{
	ImageBuf * imageBuf = NULL;
	ImageSpec imageSpec( header.width / 4, header.length / 4, 1, TypeDesc::UINT8 );
	unsigned char *data = new unsigned char[ imageSpec.image_pixels() ];

	ifstream smf( loadFile.c_str() );
	if( smf.good() ) {
		smf.seekg(80);

		int offset;
		SMFEH extraHeader;
		SMFEHGrass grassHeader;
		for(int i = 0; i < header.nExtraHeaders; ++i ) {
			offset = smf.tellg();
			smf.read( (char *)&extraHeader, sizeof(SMFEH) );
			smf.seekg(offset);
			if(extraHeader.type == 1) {
				smf.read( (char *)&grassHeader, sizeof(SMFEHGrass));
			}
			smf.seekg( offset + extraHeader.size);
		}
		smf.seekg(grassHeader.grassPtr);
		smf.read( (char *)data, imageSpec.image_bytes() );
		imageBuf = new ImageBuf( "grass", imageSpec, data );
	}
	smf.close();
	return imageBuf;
}
Exemple #2
0
TEST_F(SMFTrackTest, pause)
{
  SMF smf(song_);
  SMFTrack t(smf);
  t.setup(MTRK_00, sizeof MTRK_00 - 1);
  EXPECT_EQ(false, t.is_playing());
  EXPECT_EQ(false, t.is_paused());
  t.pause();
  EXPECT_EQ(false, t.is_playing());
  EXPECT_EQ(true, t.is_paused());
  t.update();
  EXPECT_EQ(false, t.is_playing());
  EXPECT_EQ(true, t.is_paused());
  t.play();
  EXPECT_EQ(true, t.is_playing());
  EXPECT_EQ(true, t.is_paused());
  t.update();
  EXPECT_EQ(true, t.is_playing());
  EXPECT_EQ(true, t.is_paused());
  t.resume();
  EXPECT_EQ(true, t.is_playing());
  EXPECT_EQ(false, t.is_paused());
  t.update();
  EXPECT_EQ(false, t.is_playing());
  EXPECT_EQ(false, t.is_paused());
}
Exemple #3
0
bool
SMF::saveFeatures()
{
	if( verbose )cout << "INFO: saveFeatures\n";

	char filename[256];
	sprintf( filename, "%s.smf", outPrefix.c_str() );

	fstream smf(filename, ios::binary | ios::in | ios::out);
	smf.seekp(featuresPtr);

	int nTypes = featureTypes.size();
	smf.write( (char *)&nTypes, 4); //featuretypes
	int nFeatures = features.size();
	smf.write( (char *)&nFeatures, sizeof(nFeatures)); //numfeatures
	if( verbose ) printf( "    %i features, %i types.\n", nFeatures, nTypes);

	for(unsigned int i = 0; i < featureTypes.size(); ++i ) {
		smf.write(featureTypes[i].c_str(), featureTypes[i].size() + 1 );
	}

	for(unsigned int i = 0; i < features.size(); ++i ) {
		smf.write( (char *)&features[i], sizeof(SMFFeature) );
	}

	smf.write( "\0", sizeof("\0"));
	smf.close();
	return false;
}
Exemple #4
0
TEST_F(SMFTrackTest, setup)
{
  SMF smf(song_);
  SMFTrack t(smf);
  EXPECT_EQ(true, t.setup(MTRK_00, sizeof MTRK_00 - 1));
  EXPECT_EQ(false, t.setup("ABCDEFG", 7));
  EXPECT_EQ(false, t.setup("ABCDEFGH", 8));
  EXPECT_EQ(false, t.setup("MTrk\x00\x00\x10\x00", 8));
}
Exemple #5
0
/** Read smf formatted file, create a temporary mesh and write a vtk file
 */
int main( int argc, char * argv[] )
{
    namespace smf2vtk   = tools::converter::smf2vtk;
    namespace smf2xx    = tools::converter::smf2xx;

    // Sanity check of the number of input arguments
    if ( argc != 2 ) {
        std::cout << "Usage:  " << argv[0]
                  << " file.smf \n\n";
        return 0;
    }

    // Name of smf input file, its basename and the vtk output file name
    const std::string smfFile = boost::lexical_cast<std::string>( argv[1] );
    const std::string base    = smfFile.substr(0, smfFile.find( ".smf") );
    const std::string vtkFile = base + ".vtk";

    // Element attributes
    base::Shape elementShape;
    unsigned    elementNumPoints;
    
    {
        // extract data from header
        std::ifstream smf( smfFile.c_str() );
        smf2xx::readSMFHeader( smf, elementShape, elementNumPoints );
        smf.close();
    }

    // Input and output file streams
    std::ifstream smf( smfFile.c_str() );
    std::ofstream vtk( vtkFile.c_str() );

    // Call generic conversion helper
    smf2xx::Conversion< smf2vtk::Converter >::apply( elementShape,
                                                     elementNumPoints,
                                                     smf, vtk );

    // Close the streams
    smf.close();
    vtk.close();
    
    return 0;
}
Exemple #6
0
void generateMesh( MESH& mesh, const UIN& userInput ) 
{
    if ( userInput.readMeshFromFile ) {
        std::ifstream smf( userInput.meshFile.c_str() );
        VERIFY_MSG( smf.is_open(),
                    x2s("Cannot find input file ") + userInput.meshFile );
        base::io::smf::readMesh( smf, mesh );
    }
    else {
        ::generateMesh<UIN::dim>( mesh, userInput.N, userInput.bbmin, userInput.bbmax );
    }
}
Exemple #7
0
TEST_F(SMFTrackTest, play)
{
  SMF smf(song_);
  SMFTrack t(smf);
  t.setup(MTRK_01, sizeof MTRK_01 - 1);
  EXPECT_EQ(false, t.is_playing());
  t.play();
  EXPECT_EQ(true, t.is_playing());
  for (int i = 0; i < 6; ++i) {
    t.update();
    EXPECT_EQ(true, t.is_playing());
  }
  t.update();
  EXPECT_EQ(false, t.is_playing());
}
Exemple #8
0
ImageBuf *
SMF::getHeight()
{
	ImageBuf *imageBuf = NULL;
	ImageSpec imageSpec( header.width + 1, header.length + 1, 1, TypeDesc::UINT16 );
	unsigned short *data = new unsigned short[ imageSpec.image_pixels() ];

	ifstream smf( loadFile.c_str() );
	if( smf.good() ) {
		smf.seekg(header.heightPtr);
		smf.read( (char *)data, imageSpec.image_bytes() );
		imageBuf = new ImageBuf( "height", imageSpec, data);
	}
	smf.close();
	return imageBuf;
}
Exemple #9
0
ImageBuf *
SMF::getMetal()
{
	ImageBuf * imageBuf = NULL;
	ImageSpec imageSpec( header.width / 2, header.length / 2, 1, TypeDesc::UINT8 );
	unsigned char *data = new unsigned char[ imageSpec.image_pixels() ];

	ifstream smf( loadFile.c_str() );
	if( smf.good() ) {
		smf.seekg( header.metalPtr );
		smf.read( (char *)data, imageSpec.image_bytes() );
		imageBuf = new ImageBuf( "metal", imageSpec, data );
	}
	smf.close();
	return imageBuf;
}
Exemple #10
0
bool
is_smf(string filename)
{
	char magic[16];
	// Perform tests for file validity
	ifstream smf(filename.c_str(), ifstream::in);
	if( smf.good() ) {
		smf.read( magic, 16);
		// perform test for file format
		if( !strcmp(magic, "spring map file") ) {
			smf.close();
			return true;
		}
	}
	return false;
}
Exemple #11
0
    // create a mesh and read from input
    Solid( const std::string meshFile,
           const double E, const double nu )
        : E_( E ),
          material_( mat::Lame::lambda( E, nu), mat::Lame::mu( E, nu ) ),
          hyperElasticSpatial_(  material_ ),
          hyperElasticMaterial_( material_ ),
          fieldBinder_( mesh_, current_ )
    {
        std::ifstream smf( meshFile.c_str() );
        base::io::smf::readMesh( smf, mesh_ );
        smf.close();

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

        solid::initialiseGeometry( mesh_, current_ );
    }
Exemple #12
0
ImageBuf *
SMF::getMinimap()
{
	ImageBuf * imageBuf = NULL;
	ImageSpec imageSpec( 1024, 1024, 4, TypeDesc::UINT8 );
	unsigned char *data;

	ifstream smf( loadFile.c_str() );
	if( smf.good() ) {
		unsigned char *temp = new unsigned char[MINIMAP_SIZE];
		smf.seekg( header.minimapPtr );
		smf.read( (char *)temp, MINIMAP_SIZE);
		data = dxt1_load(temp, 1024, 1024);
		delete [] temp;
		imageBuf = new ImageBuf( "minimap", imageSpec, data );
	}
	smf.close();
	return imageBuf;
}
Exemple #13
0
TEST_F(SMFTrackTest, inspect)
{
  SMF smf(song_);
  SMFTrack t(smf);
  EXPECT_EQ(std::string("#<SMFTrack NONE>"), t.inspect());
  t.setup(MTRK_01, sizeof MTRK_01 - 1);
  EXPECT_EQ(std::string("#<SMFTrack INITIALIZED>"), t.inspect());
  t.play();
  EXPECT_EQ(std::string("#<SMFTrack PLAYING>"), t.inspect());
  t.pause();
  EXPECT_EQ(std::string("#<SMFTrack PLAYING PAUSED>"), t.inspect());
  t.update();
  EXPECT_EQ(std::string("#<SMFTrack PLAYING PAUSED>"), t.inspect());
  t.resume();
  EXPECT_EQ(std::string("#<SMFTrack PLAYING>"), t.inspect());
  t.update();
  EXPECT_EQ(std::string("#<SMFTrack PLAYING>"), t.inspect());
  t.stop();
  EXPECT_EQ(std::string("#<SMFTrack STOPPED>"), t.inspect());
  t.update();
  EXPECT_EQ(std::string("#<SMFTrack STOPPED>"), t.inspect());
}
Exemple #14
0
ImageBuf *
SMF::getTilemap()
{
	ImageBuf * imageBuf = NULL;
	ImageSpec imageSpec( header.width / 4, header.length / 4, 1, TypeDesc::UINT );
	unsigned int *data = new unsigned int[ imageSpec.image_pixels() ];

	ifstream smf( loadFile.c_str() );
	if( smf.good() ) {
		smf.seekg( header.tilesPtr );
		int numFiles = 0;
		smf.read( (char *)&numFiles, 4 );
		smf.ignore( 4 );
		for( int i = 0; i < numFiles; ++i ) { 
			smf.ignore(4);
			smf.ignore(255, '\0');
		}

		smf.read( (char *)data, imageSpec.image_bytes() );
		imageBuf = new ImageBuf( "tilemap", imageSpec, data );
	}
	smf.close();
	return imageBuf;
}
Exemple #15
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;
}
Exemple #16
0
//------------------------------------------------------------------------------
int main( int argc, char * argv[] )
{
    // basic attributes of the computation
    const unsigned    geomDeg  = 1;
    const unsigned    fieldDeg = 1;
    const unsigned    dim      = 2;
    const base::Shape shape    = base::SimplexShape<dim-1>::value;

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

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

    // read from input file
    std::string meshFile;
    double A, B, tolerance, pressure;
    unsigned maxIter, loadSteps;
    {    
        //Feed properties parser with the variables to be read
        base::io::PropertiesParser prop;
        prop.registerPropertiesVar( "meshFile",         meshFile );
        prop.registerPropertiesVar( "A",                A );
        prop.registerPropertiesVar( "B",                B );
        prop.registerPropertiesVar( "maxIter",          maxIter );
        prop.registerPropertiesVar( "loadSteps",        loadSteps );
        prop.registerPropertiesVar( "tolerance",        tolerance );
        prop.registerPropertiesVar( "pressure",         pressure );

        // 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,dim>    Mesh;

    // 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 = 1; //3;
    typedef base::Quadrature<kernelDegEstimate,shape> Quadrature;
    Quadrature quadrature;
    
    // 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 );


    // constrain a dof
    constrainSupports( field );

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

    // material object
    typedef surf::Skalak Energy;
    Energy   energy( A, B );

    //typedef surf::NeoHookean Energy;
    //Energy   energy( A  );

    typedef surf::HyperElasticMembrane<Energy> Material;
    Material material( energy );

    // 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;

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

    // load increment
    const double deltaP = pressure / static_cast<double>( loadSteps );

    std::cout << "# pressure   radius \n"
              << 0.0  << "   "  << giveRadius( mesh, field ) << "\n";
    
    //--------------------------------------------------------------------------
    // Loop over load steps
    //--------------------------------------------------------------------------
    for ( unsigned step = 0; step < loadSteps; step++ ) {

        // current load
        const double p = (step+1) * deltaP;

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

            //std::cout << "Iter " << iter;

            // Create a solver object
            typedef base::solver::Eigen3           Solver;
            Solver solver( numDofs );

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

            // internal pressure load
            base::asmb::bodyForceComputation2<FTB>( quadrature, solver, fieldBinder,
                                                    boost::bind( &internalPressure<Mesh::Element>,
                                                                 _1, _2, p ) );


            // Finalise assembly
            solver.finishAssembly();

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

            //std::cout << " |F| = " << conv1;

            // convergence via residual norm
            if ( conv1 < tolerance * A ) { // note the tolerance multiplier
                //std::cout << "\n";
                break;
            }

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

            // norm of displacement increment
            const double conv2 = solver.norm();
            //std::cout << " | DU | = " << conv2 << "\n";
            
            // convergence via increment
            if ( conv2 < tolerance ) break;

            iter++;

        }
        // Finished non-linear iterations
        //----------------------------------------------------------------------

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

        // write a vtk file
        writeVTKFile( baseName, step+1, mesh, field, material );

        std::cout << p << " " << giveRadius( mesh, field ) << std::endl;

    }
    // Finished load steps
    //--------------------------------------------------------------------------

    
    return 0;
}
Exemple #17
0
//------------------------------------------------------------------------------
int main( int argc, char * argv[] )
{
    // basic attributes of the computation
    const unsigned    geomDeg   = 1;
    const unsigned    fieldDegU = 2;
    const unsigned    fieldDegP = 1;
    const unsigned    tiOrder   = 2;   // order of time integrator
    const base::Shape shape     = base::QUAD;

    //typedef  base::time::BDF<tiOrder> MSM;
    typedef base::time::AdamsMoulton<tiOrder> MSM;

    // time stepping method determines the history size
    const unsigned nHist = MSM::numSteps;

    
    const std::string inputFile = "terz.inp";
    double E, nu, alpha, c0, k, H, F, tMax;
    unsigned numSteps, numIntervals;
    {
        base::io::PropertiesParser pp;
        pp.registerPropertiesVar( "E",     E     );
        pp.registerPropertiesVar( "nu",    nu    );
        pp.registerPropertiesVar( "alpha", alpha );
        pp.registerPropertiesVar( "c0",    c0    );
        pp.registerPropertiesVar( "k",     k     );
        pp.registerPropertiesVar( "H",     H     );
        pp.registerPropertiesVar( "F",     F     );

        pp.registerPropertiesVar( "tMax",         tMax  );
        pp.registerPropertiesVar( "numSteps",     numSteps );
        pp.registerPropertiesVar( "numIntervals", numIntervals );

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

    }

    const double deltaT = tMax / static_cast<double>( numSteps );

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

    const std::string meshFile = boost::lexical_cast<std::string>( argv[1] );

    

    // Analytic solution
    Terzaghi terzaghi( E, nu, alpha, c0, k, H, F );
    

    //--------------------------------------------------------------------------
    // 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 displacement field
    const unsigned    doFSizeU = dim;
    typedef base::fe::Basis<shape,fieldDegU>           FEBasisU;
    typedef base::Field<FEBasisU,doFSizeU,nHist>       Displacement;
    typedef Displacement::DegreeOfFreedom              DoFU;
    Displacement displacement;

    // Create a pressure field
    const unsigned    doFSizeP = 1;
    typedef base::fe::Basis<shape,fieldDegP>           FEBasisP;
    typedef base::Field<FEBasisP,doFSizeP,nHist>       Pressure;
    typedef Pressure::DegreeOfFreedom                  DoFP;
    Pressure pressure;

    // generate DoFs from mesh
    base::dof::generate<FEBasisU>( mesh, displacement );
    base::dof::generate<FEBasisP>( mesh, pressure );

    // 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::CreateBoundaryMesh<Mesh::Element> CreateBoundaryMesh;
    typedef CreateBoundaryMesh::BoundaryMesh BoundaryMesh;
    BoundaryMesh boundaryMesh;
    {
        CreateBoundaryMesh::apply( meshBoundary.begin(),
                                   meshBoundary.end(),
                                   mesh, boundaryMesh );
    }



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

    typedef base::asmb::FieldBinder<Mesh,Displacement,Pressure> Field;
    Field field( mesh, displacement, pressure );

    typedef Field::TupleBinder<1,1>::Type TopLeft;
    typedef Field::TupleBinder<1,2>::Type TopRight;
    typedef Field::TupleBinder<2,1>::Type BotLeft;
    typedef Field::TupleBinder<2,2>::Type BotRight;

    // surface displacement field
    typedef base::asmb::SurfaceFieldBinder<BoundaryMesh,Displacement> SurfaceFieldBinder;
    SurfaceFieldBinder surfaceFieldBinder( boundaryMesh, displacement );
    typedef SurfaceFieldBinder::TupleBinder<1>::Type SFTB;
    
    // kernel objects
    typedef solid::HyperElastic<Material,TopLeft::Tuple> HyperElastic;
    HyperElastic hyperElastic( material );

    typedef fluid::PressureGradient<TopRight::Tuple> GradP;
    GradP gradP;

    //typedef fluid::VelocityDivergence<FieldPUUTuple> DivU;
    //DivU divU( true ); // * alpha
    typedef PoroDivU<BotLeft::Tuple> DivU;
    DivU divU( alpha );

    typedef heat::Laplace<BotRight::Tuple> Laplace;
    Laplace laplace( k );

    // constrain the boundary
    base::dof::constrainBoundary<FEBasisU>( meshBoundary.begin(),
                                            meshBoundary.end(),
                                            mesh, displacement, 
                                            boost::bind( &dirichletU<dim,DoFU>, _1, _2, 1.0 ) );
    
    base::dof::constrainBoundary<FEBasisP>( meshBoundary.begin(),
                                            meshBoundary.end(),
                                            mesh, pressure, 
                                            boost::bind( &dirichletP<dim,DoFP>, _1, _2, H ) );


    // Number the degrees of freedom
    const std::size_t numDoFsU =
        base::dof::numberDoFsConsecutively( displacement.doFsBegin(), displacement.doFsEnd() );
    std::cout << "# Number of displacement dofs " << numDoFsU << std::endl;
    const std::size_t numDoFsP =
        base::dof::numberDoFsConsecutively( pressure.doFsBegin(), pressure.doFsEnd(), numDoFsU );
    std::cout << "# Number of pressure     dofs " << numDoFsP << std::endl;


    // write VTK file
    writeVTK( mesh, displacement, pressure, meshFile, 0 );

    
    for ( unsigned n = 0; n < numSteps; n++ ) {

        const double time = (n+1) * deltaT;
        std::cout << time << "  ";

        // initialise current displacement to zero (linear elasticity)
        std::for_each( displacement.doFsBegin(), displacement.doFsEnd(),
                       boost::bind( &DoFU::clearValue, _1 ) );

        // Create a solver object
        typedef base::solver::Eigen3           Solver;
        Solver solver( numDoFsU + numDoFsP );

        //------------------------------------------------------------------
        base::asmb::stiffnessMatrixComputation<TopLeft>( quadrature, solver, 
                                                         field, hyperElastic );

        base::asmb::stiffnessMatrixComputation<TopRight>( quadrature, solver,
                                                          field, gradP );

        base::asmb::stiffnessMatrixComputation<BotRight>( quadrature, solver,
                                                          field, laplace);

        // time integration terms
        base::time::computeReactionTerms<BotLeft,MSM>( divU, quadrature, solver,
                                                       field, deltaT, n );

        base::time::computeInertiaTerms<BotRight,MSM>( quadrature, solver,
                                                       field, deltaT, n, c0 );
        
        base::time::computeResidualForceHistory<BotRight,MSM>( laplace, 
                                                               quadrature, solver,
                                                               field, n );


        // Neumann boundary condition
        base::asmb::neumannForceComputation<SFTB>( surfaceQuadrature, solver, surfaceFieldBinder,
                                                   boost::bind( &neumannBC<dim>, _1, _2,
                                                                H, F ) );


        // Finalise assembly
        solver.finishAssembly();

        // Solve
        solver.superLUSolve();
            
        // distribute results back to dofs
        base::dof::setDoFsFromSolver( solver, displacement );
        base::dof::setDoFsFromSolver( solver, pressure );
        
        // push history
        std::for_each( displacement.doFsBegin(), displacement.doFsEnd(),
                       boost::bind( &DoFU::pushHistory, _1 ) );
        std::for_each( pressure.doFsBegin(), pressure.doFsEnd(),
                       boost::bind( &DoFP::pushHistory, _1 ) );


        // write VTK file
        writeVTK( mesh, displacement, pressure, meshFile, n+1 );
        
        // Finished time steps
        //--------------------------------------------------------------------------

        const std::pair<double,double> approx = probe( mesh, displacement, pressure );

        const double p = terzaghi.pressure( H/2., time );
        const double u = terzaghi.displacement( H/2., time );
        
        std::cout << u  << "  " << approx.first << "  "
                  << p  << "  " << approx.second << '\n';
    }
    
    return 0;
}
Exemple #18
0
bool
SMF::decompileFeaturelist(int format = 0)
{
	if( features.size() == 0) return true;
	if( verbose )cout << "INFO: Decompiling Feature List. "
		<< header.featuresPtr << endl;

	char filename[256];
	if(format == 0)
		sprintf( filename, "%s_featurelist.csv", outPrefix.c_str() );
	else if (format == 1)
		sprintf( filename, "%s_featurelist.lua", outPrefix.c_str() );

	ofstream outfile(filename);

	ifstream smf(loadFile.c_str(), ifstream::in);
	if( !smf.good() ) {
		return true;
	}

	smf.seekg( header.featuresPtr );

	int nTypes;
	smf.read( (char *)&nTypes, 4);

	int nFeatures;
	smf.read( (char *)&nFeatures, 4);

	char name[256];
	vector<string> featureNames;
	for( int i = 0; i < nTypes; ++i ) {
		smf.getline(name,255, '\0');
		featureNames.push_back(name);
	}

	char line[1024];
	SMFFeature feature;
	for( int i=0; i < nFeatures; ++i ) {
//		READ_SMFFEATURE(temp,&smf);
		smf.read( (char *)&feature, sizeof(SMFFeature) );

		if(format == 0) {
				outfile << featureNames[feature.type] << ',';
				outfile << feature.x << ',';
				outfile << feature.y << ',';
				outfile << feature.z << ',';
				outfile << feature.r << ',';
				outfile << feature.s << endl;
			} else if (format == 1) {
				sprintf(line, "\t\t{ name = '%s', x = %i, z = %i, rot = \"%i\",},\n",
					featureNames[feature.type].c_str(),
					(int)feature.x, (int)feature.z, (int)feature.r * 32768 );
				outfile << line;
			}

	}
	smf.close();
	outfile.close();

	return false;
}
Exemple #19
0
bool
SMF::saveMinimap()
{
	if( verbose )cout << "INFO: saveMinimap\n";

	char filename[256];
	sprintf( filename, "%s.smf", outPrefix.c_str() );

	fstream smf(filename, ios::binary | ios::in | ios::out);
	smf.seekp(minimapPtr);

	unsigned char *pixels;
	if( is_smf(minimapFile) ) {
		// Copy from SMF
		pixels = new unsigned char[MINIMAP_SIZE];

		ifstream inFile(minimapFile.c_str(), ifstream::in);
		inFile.seekg(header.minimapPtr);
		inFile.read( (char *)pixels, MINIMAP_SIZE);
		inFile.close();

		smf.write( (char *)pixels, MINIMAP_SIZE);
		smf.close();
		delete [] pixels;
		return false;
	}

	//OpenImageIO
	ROI roi(	0, 1024,
				0, 1024,
				0, 1,
				0, 4);
	ImageSpec imageSpec( roi.xend, roi.yend, roi.chend, TypeDesc::UINT8 );
	

	// Load image file
	ImageBuf *imageBuf = new ImageBuf( minimapFile );
	imageBuf->read( 0, 0, false, TypeDesc::UINT8 );
//FIXME attempt to generate minimap from tile files.

	if( !imageBuf->initialized() ) {
		// Create from height
		imageBuf->reset( minimapFile );
		imageBuf->read( 0, 0, false, TypeDesc::UINT8 );
	}

	if( !imageBuf->initialized() ) {
		// Create blank
		imageBuf->reset( "minimap", imageSpec);
	}

	imageSpec = imageBuf->specmod();
	ImageBuf fixBuf;
	// Fix channels
	if( imageSpec.nchannels != roi.chend ) {
		int map[] = {2,1,0,3};
		float fill[] = {0,0,0,255};
		ImageBufAlgo::channels(fixBuf, *imageBuf, roi.chend, map, fill);
		imageBuf->copy(fixBuf);
		fixBuf.clear();
	}

	// Fix dimensions
	if( imageSpec.width != roi.xend || imageSpec.height != roi.yend ) {
		printf( "\tWARNING: %s is (%i,%i), wanted (%i, %i), Resampling.\n",
			minimapFile.c_str(), imageSpec.width, imageSpec.height, roi.xend, roi.yend );
		ImageBufAlgo::resample(fixBuf, *imageBuf, true, roi);
		imageBuf->copy(fixBuf);
		fixBuf.clear();
	}

	pixels = (unsigned char *)imageBuf->localpixels();

	// setup DXT1 Compression
	nvtt::InputOptions inputOptions;
	inputOptions.setTextureLayout( nvtt::TextureType_2D, 1024, 1024 );
	inputOptions.setMipmapData( pixels, 1024, 1024 );

	nvtt::CompressionOptions compressionOptions;
	compressionOptions.setFormat( nvtt::Format_DXT1 );
	if( slowcomp ) compressionOptions.setQuality( nvtt::Quality_Normal ); 
	else compressionOptions.setQuality( nvtt::Quality_Fastest ); 

	nvtt::OutputOptions outputOptions;
	outputOptions.setOutputHeader( false );

	NVTTOutputHandler *outputHandler = new NVTTOutputHandler(MINIMAP_SIZE + 1);
	outputOptions.setOutputHandler( outputHandler );

	nvtt::Compressor compressor;
	compressor.process( inputOptions, compressionOptions, outputOptions );

	// Write data to smf
	smf.write( outputHandler->buffer, MINIMAP_SIZE );
	delete outputHandler;

	smf.close();
	delete imageBuf;		
	return false;
}
Exemple #20
0
bool
SMF::saveHeight()
{
	if( verbose )cout << "INFO: saveHeight\n";
	// Dimensions of displacement map.
	ImageBuf *imageBuf = NULL;
	ROI roi(	0, width * 64 + 1,  // xbegin, xend
				0, length * 64 + 1, // ybegin, yend
				0, 1,               // zbegin, zend
				0, 1);              // chbegin, chend
	ImageSpec imageSpec( roi.xend, roi.yend, roi.chend, TypeDesc::UINT16 );

	if( is_smf(heightFile) ) {
		// Load from SMF
		SMF sourcesmf(heightFile);
		imageBuf = sourcesmf.getHeight();
	}
   	if( !imageBuf ) {
		// load image file
		imageBuf = new ImageBuf( heightFile );
		imageBuf->read( 0, 0, false, TypeDesc::UINT16 );
		if( !imageBuf->initialized() ) {
			delete imageBuf;
			imageBuf = NULL;
		}
	}
	if( !imageBuf ) {
		// Generate blank
		imageBuf = new ImageBuf( "height", imageSpec );
	}

	imageSpec = imageBuf->specmod();
	ImageBuf fixBuf;
	// Fix the number of channels
	if( imageSpec.nchannels != roi.chend ) {
		int map[] = {0};
		ImageBufAlgo::channels(fixBuf, *imageBuf, roi.chend, map);
		imageBuf->copy(fixBuf);
		fixBuf.clear();
	}

	// Fix the size
	if ( imageSpec.width != roi.xend || imageSpec.height != roi.yend ) {
		if( verbose )
			printf( "\tWARNING: %s is (%i,%i), wanted (%i, %i), Resampling.\n",
			heightFile.c_str(), imageSpec.width, imageSpec.height, roi.xend, roi.yend );
		ImageBufAlgo::resample(fixBuf, *imageBuf, true, roi);
		imageBuf->copy(fixBuf);
		fixBuf.clear();
	}

	// Invert height
	if ( invert ) {
		ImageSpec fixSpec(roi.xend, roi.yend, roi.chend, TypeDesc::UINT16);
		fixBuf.reset( "fixBuf",  fixSpec );
		const float fill[] = {65535};
		ImageBufAlgo::fill(fixBuf, fill);
		ImageBufAlgo::sub(*imageBuf, fixBuf, *imageBuf);
		fixBuf.clear();
	}

	// FIXME filter to remove stepping artifacts from 8bit images,
//	if ( lowpass ) {
//	}
	
	unsigned short *pixels = (unsigned short *)imageBuf->localpixels();

	// write height data to smf.
	char filename[256];
	sprintf( filename, "%s.smf", outPrefix.c_str() );

	fstream smf(filename, ios::binary | ios::in| ios::out);
	smf.seekp(heightPtr);

	smf.write( (char *)pixels, imageBuf->spec().image_bytes() );
	smf.close();
	delete imageBuf;
	if( is_smf( heightFile ) ) delete [] pixels;

	return false;
}
Exemple #21
0
bool
SMF::saveMetal()
{
	if( verbose )cout << "INFO: saveMetal\n";

	// Dimensions of displacement map.
	ImageBuf *imageBuf = NULL;
	ROI roi(	0, width * 32,  // xbegin, xend
				0, length * 32, // ybegin, yend
				0, 1,               // zbegin, zend
				0, 1);              // chbegin, chend
	ImageSpec imageSpec( roi.xend, roi.yend, roi.chend, TypeDesc::UINT8 );

	if( is_smf(metalFile) ) {
		// Load from smf
		SMF sourcesmf(metalFile);
		imageBuf = sourcesmf.getMetal();
	}
	if( !imageBuf ) {
		//load from image
		imageBuf = new ImageBuf(metalFile);
		imageBuf->read( 0, 0, false, TypeDesc::UINT8 );
		if( !imageBuf->initialized() ) {
			delete imageBuf;
			imageBuf = NULL;
		}
	}
	if( !imageBuf ) {
		// Generate blank
		imageBuf = new ImageBuf( "metal", imageSpec );
	}

	imageSpec = imageBuf->specmod();
	ImageBuf fixBuf;
	// Fix the number of channels
	if( imageSpec.nchannels != roi.chend ) {
		int map[] = {0};
		ImageBufAlgo::channels(fixBuf, *imageBuf, roi.chend, map);
		imageBuf->copy(fixBuf);
		fixBuf.clear();
	}

	// Fix the size
	if ( imageSpec.width != roi.xend || imageSpec.height != roi.yend ) {
		if( verbose )
			printf( "\tWARNING: %s is (%i,%i), wanted (%i, %i), Resampling.\n",
			metalFile.c_str(), imageSpec.width, imageSpec.height, roi.xend, roi.yend );
		ImageBufAlgo::resample(fixBuf, *imageBuf, true, roi);
		imageBuf->copy(fixBuf);
		fixBuf.clear();
	}

	unsigned char *pixels = (unsigned char *)imageBuf->localpixels();


	char filename[256];
	sprintf( filename, "%s.smf", outPrefix.c_str() );

	fstream smf(filename, ios::binary | ios::in | ios::out);
	smf.seekp(metalPtr);

	// write the data to the smf
	smf.write( (char *)pixels, imageBuf->spec().image_bytes() );
	smf.close();

	delete imageBuf;
	if( is_smf( metalFile ) ) delete [] pixels;

	return false;
}
Exemple #22
0
bool
SMF::saveTilemap()
{
	if( verbose )cout << "INFO: saveTilemap\n";

	char filename[256];
	sprintf( filename, "%s.smf", outPrefix.c_str() );

	fstream smf(filename, ios::binary | ios::in | ios::out);
	smf.seekp(tilesPtr);

	// Tiles Header
	int nTileFiles = smtList.size();
	smf.write( (char *)&nTileFiles, 4);
	smf.write( (char *)&nTiles, 4);
	if(verbose)printf( "    %i tiles referenced in %i files\n", nTiles, nTileFiles );

	// SMT Names
	for(unsigned int i = 0; i < smtList.size(); ++i) {
		if( verbose )printf( "\t%i %s\n", smtTiles[i], smtList[i].c_str() );
		smf.write( (char *)&smtTiles[i], 4);
		smf.write( smtList[i].c_str(), smtList[i].size() +1 );
	}

	// Dimensions of displacement map.
	ImageBuf *imageBuf = NULL;
	ROI roi(	0, width * 16,  // xbegin, xend
				0, length * 16, // ybegin, yend
				0, 1,               // zbegin, zend
				0, 1);              // chbegin, chend
	ImageSpec imageSpec( roi.xend, roi.yend, roi.chend, TypeDesc::UINT );

	if( is_smf(tilemapFile) ) {
		// Load from SMF
		SMF sourcesmf(tilemapFile);
		imageBuf = sourcesmf.getTilemap();
	}
   	if( !imageBuf ) {
		// load image file
		imageBuf = new ImageBuf( tilemapFile );
		imageBuf->read( 0, 0, false, TypeDesc::UINT );
		if( !imageBuf->initialized() ) {
			delete imageBuf;
			imageBuf = NULL;
		}
	}
	if( !imageBuf ) {
		// Generate blank
		imageBuf = new ImageBuf( "tilemap", imageSpec );
		for ( unsigned int i = 0; i < imageSpec.image_pixels(); ++i )
			((unsigned int *)imageBuf->localpixels())[ i ] = i;
	}

	imageSpec = imageBuf->specmod();
	ImageBuf fixBuf;
	// Fix the number of channels
	if( imageSpec.nchannels != roi.chend ) {
		int map[] = {0};
		ImageBufAlgo::channels(fixBuf, *imageBuf, roi.chend, map);
		imageBuf->copy(fixBuf);
		fixBuf.clear();
	}

	// Fix the size
	// FIXME image should never be resized, instead tiling either from an edge or centred.
	if ( imageSpec.width != roi.xend || imageSpec.height != roi.yend ) {
		if( verbose )
			printf( "\tWARNING: %s is (%i,%i), wanted (%i, %i), Resampling.\n",
			tilemapFile.c_str(), imageSpec.width, imageSpec.height, roi.xend, roi.yend );
		ImageBufAlgo::resample(fixBuf, *imageBuf, false, roi);
		imageBuf->copy(fixBuf);
		fixBuf.clear();
	}

	unsigned int *pixels = (unsigned int *)imageBuf->localpixels();

	// write the data to the smf
	smf.write( (char *)pixels, imageBuf->spec().image_bytes() );
	smf.close();

	delete imageBuf;
	if( is_smf( tilemapFile ) ) delete [] pixels;

	return false;
}
Exemple #23
0
/** In- and output of an unstructured mesh.
 *  This function demonstrates
 *     - how to define and create a mesh
 *     - read a  mesh from a file (base::io::smf)
 *     - extract the boundary from the mesh
 *     - write output in vtk and SMF format
 *
 *  The image shows the reference meshes in this application
 *  \image html simplexMeshes.png "Triangle (left) and tetrahedron mesh (right)"
 *  and the boundary meshes are given in the next picture
 *  \image html boundaryMeshes.png "Line (left) and triangle mesh(right)"
 *
 *  \param[in] argc Number of command line arguments
 *  \param[in] argv Values of command line arguments
 */
int ref01::unstructured( int argc, char* argv[] )
{
    //--------------------------------------------------------------------------
    // Definition of the spatial dimension
    const unsigned dim = SPACEDIM;
    // Defintion of an element shape
    const base::Shape elemShape = base::SimplexShape<dim>::value;
    // Definition of the polynomial degree of the geometry approximation
    const unsigned geomDeg = 1;

    // Check the number of input arguments
    if ( argc != 2 ) { // note argv[0] is the program name itself
        usageMessage1<elemShape,geomDeg>( argv[0] );
        return 0;
    }
    // convert input argument to a string object
    const std::string smfFileName = boost::lexical_cast<std::string>( argv[1] );
    // extract the basename of the file
    const std::string baseName = base::io::baseName( smfFileName, ".smf" );

    typedef base::Unstructured<elemShape,geomDeg>            Mesh;

    // Create an empty mesh object
    Mesh mesh;

    //--------------------------------------------------------------------------
    {
        // input file stream from smf file
        std::ifstream smf( smfFileName.c_str() );
        // read smf mesh
        base::io::smf::readMesh( smf, mesh );
        // close the stream
        smf.close();
    }

    //--------------------------------------------------------------------------
    typedef base::mesh::BoundaryMeshBinder<Mesh::Element>::Type BoundaryMesh;
    BoundaryMesh boundaryMesh;
    {
        // Create list of <Element,faceNo> pairs
        base::mesh::MeshBoundary meshBoundary;
        meshBoundary.create( mesh.elementsBegin(), mesh.elementsEnd() );

        // Create a real mesh object from this list
        base::mesh::generateBoundaryMesh( meshBoundary.begin(),
                                          meshBoundary.end(),
                                          mesh, boundaryMesh );
    }

    //--------------------------------------------------------------------------
    // Output functions
    {

        // VTK file of the input mesh
        {
            // file name for vtk mesh file
            const std::string vtkMeshFileName = baseName + ".vtk";
            // output file stream 
            std::ofstream vtk( vtkMeshFileName.c_str() );
            // create a VTK writer
            base::io::vtk::LegacyWriter vtkWriter( vtk );
            // write the mesh
            vtkWriter.writeUnstructuredGrid( mesh );
            // close the stream
            vtk.close();
        }

        // SMF file of the boundary mesh
        {
            // file name for boundary mesh output
            const std::string smfBoundaryFileName = baseName + "_boundary.smf";
            // output stream
            std::ofstream smf( smfBoundaryFileName.c_str() );
            // write to smf
            base::io::smf::writeMesh( boundaryMesh, smf );
            // close stream
            smf.close();
        }
        
    }


    return 0;
}
Exemple #24
0
bool
SMF::load(string filename)
{
	bool ret = false;
	char magic[16];

	// Perform tests for file validity
	ifstream smf(filename.c_str(), ifstream::in);
	if( !smf.good() ) {
		if ( !quiet )printf( "ERROR: Cannot open %s\n", filename.c_str() ); 
		ret = true;
	}
	
	smf.read( magic, 16);
	// perform test for file format
	if( strcmp(magic, "spring map file") ) {
		if( !quiet )printf("ERROR: %s is not a valid smf file.\n", filename.c_str() );
		ret = true;
	}

	if( ret ) return ret;

	heightFile = typeFile = minimapFile = metalFile = grassFile
		= tilemapFile = featuresFile = filename;
	loadFile = filename;

	smf.seekg(0);
	smf.read( (char *)&header, sizeof(SMFHeader) );

	// convert internal units to spring map units.
	width = header.width / 64;
	length = header.length / 64;
	floor = (float)header.floor / 512;
	ceiling = (float)header.ceiling / 512;
	heightPtr = header.heightPtr;
	typePtr = header.typePtr;
	tilesPtr = header.tilesPtr;
	minimapPtr = header.minimapPtr;
	metalPtr = header.metalPtr;
	featuresPtr = header.featuresPtr;

	if( verbose ) {
		printf("INFO: Loading %s\n", filename.c_str() );
		printf("\tVersion: %i\n", header.version );
		printf("\tID: %i\n", header.id );

		printf("\tWidth: %i\n", width );
		printf("\tLength: %i\n", length );
		printf("\tSquareSize: %i\n", header.squareWidth );
		printf("\tTexelPerSquare: %i\n", header.squareTexels );
		printf("\tTileSize: %i\n", header.tileTexels );
		printf("\tMinHeight: %f\n", floor );
		printf("\tMaxHeight: %f\n", ceiling );

		printf("\tHeightMapPtr: %i\n", heightPtr );
		printf("\tTypeMapPtr: %i\n", typePtr );
		printf("\tTilesPtr: %i\n", tilesPtr );
		printf("\tMiniMapPtr: %i\n", minimapPtr );
		printf("\tMetalMapPtr: %i\n", metalPtr );
		printf("\tFeaturePtr: %i\n", featuresPtr );

		printf("\tExtraHeaders: %i\n", header.nExtraHeaders );
	} //fi verbose

	// Extra headers Information
	int offset;
	SMFEH extraHeader;
	for(int i = 0; i < header.nExtraHeaders; ++i ) {
		if( verbose )cout << "    Extra Headers" << endl;
		offset = smf.tellg();
		smf.read( (char *)&extraHeader, sizeof(SMFEH) );
		smf.seekg(offset);
		if(extraHeader.type == 0) {
			if( verbose )printf("\tNUll type: 0\n");
			continue;
		}
		if(extraHeader.type == 1) {
			SMFEHGrass *grassHeader = new SMFEHGrass;
			smf.read( (char *)grassHeader, sizeof(SMFEHGrass));
			if( verbose )printf("\tGrass: Size %i, type %i, Ptr %i\n",
				grassHeader->size, grassHeader->type, grassHeader->grassPtr);
			extraHeaders.push_back( (SMFEH *)grassHeader );
		} else {
			ret = true;
			if( verbose )printf("WARNING: %i is an unknown header type\n", i);
		}
		smf.seekg( offset + extraHeader.size);
	}

	// Tileindex Information
	SMFHTiles tilesHeader;
	smf.seekg( header.tilesPtr );
	smf.read( (char *)&tilesHeader, sizeof( SMFHTiles ) );
	nTiles = tilesHeader.nTiles;

	if( verbose )printf("    %i tiles referenced in %i files.\n", tilesHeader.nTiles, tilesHeader.nFiles);
	
	char temp_fn[256];
	int nTiles;
	for ( int i=0; i < tilesHeader.nFiles; ++i) {
		smf.read( (char *)&nTiles, 4);
		smtTiles.push_back(nTiles);
		smf.getline( temp_fn, 255, '\0' );
		if( verbose )printf( "\t%i %s\n", nTiles, temp_fn );
		smtList.push_back(temp_fn);
	}

	// Featurelist information
	smf.seekg( header.featuresPtr );
	int nTypes;
	smf.read( (char *)&nTypes, 4);
	int nFeatures;
	smf.read( (char *)&nFeatures, 4);

	if( verbose )printf("    Features: %i, Feature types: %i\n",
			nFeatures, nTypes);
	
	offset = smf.tellg();
	smf.seekg (0, ios::end);
	int filesize = smf.tellg();
	smf.seekg(offset);

	int eeof = offset + nFeatures * sizeof(SMFFeature);
	if( eeof > filesize ) {
		if( !quiet )printf( "WARNING: Filesize is not large enough to contain the reported number of features. Ignoring feature data.\n");
		nFeatures = 0;
		nTypes = 0;
	}


	char temp[256];
	for ( int i = 0; i < nTypes; ++i ) {
		smf.getline(temp, 255, '\0' );
		featureTypes.push_back(temp);
	}

	SMFFeature feature;
	for ( int i = 0; i < nFeatures; ++i ) {
		smf.read( (char *)&feature, sizeof(SMFFeature) );
		features.push_back(feature);
	}


	smf.close();
	recalculate();
	return false;
}
Exemple #25
0
/** Solve a mixed boundary value problem based on Poisson's equation
 *
 *  New features are
 *  - application of Neumann boundary conditions and body forces
 *  - use classes to describe the reference solution and the boundary
 *    value problem
 *  - convergence analysis (if executed for many meshes)
 *
 *  The picture shows the convergence behaviour of the method
 *  for various mesh sizes, a linear finite element basis
 *  \code{.cpp}
 *  const unsigned fieldDeg = 1;
 *  \endcode
 *  and a quadratic finite element basis
 *  \code{.cpp}
 *  const unsigned fieldDeg = 2;
 *  \endcode
 *  in the \f$ L_2 \f$-norm
 *  \f[
 *         \| u - u^h \|_{L_2(\Omega)}^2
 *         = \int_\Omega (u - u^h)^2 d x
 *  \f]
 *  and the \f$ H^1 \f$-semi-norm
 *  \f[
 *         | u - u^h |_{H^1(\Omega)}^2
 *         = \int_\Omega (\nabla u - \nabla u^h)^2 d x
 *  \f]
 *
 *  \image html convergence.png "Convergence diagram"
 *
 */
int ref05::mixedPoisson( int argc, char * argv[] )
{
    if ( argc != 2 ) {
        std::cout << "Usage:  " << argv[0] << " file.smf \n\n";
        return -1;
    }

    const std::string smfFile  = boost::lexical_cast<std::string>( argv[1] );
    const std::string baseName = base::io::baseName( smfFile, ".smf" );

    //--------------------------------------------------------------------------
    const unsigned    geomDeg  = 1;
    const unsigned    fieldDeg = 2;
    const base::Shape shape    = base::QUAD;
    const unsigned    doFSize  = 1;

    //--------------------------------------------------------------------------
    typedef base::Unstructured<shape,geomDeg>     Mesh;
    const unsigned dim = Mesh::Node::dim;
    
    Mesh mesh;
    {
        std::ifstream smf( smfFile.c_str() );
        base::io::smf::readMesh( smf, mesh );
        smf.close();
    }

    // Quadrature and surface quadrature
    const unsigned kernelDegEstimate = 3;
    typedef base::Quadrature<kernelDegEstimate,shape> Quadrature;
    Quadrature quadrature;
    typedef base::SurfaceQuadrature<kernelDegEstimate,shape> SurfaceQuadrature;
    SurfaceQuadrature surfaceQuadrature;
 
    // DOF handling
    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 );

    // Object of reference solution and the Poisson problem
    typedef ReferenceSolution<dim>       RefSol;
    typedef GivenData<RefSol>            GivenData;
    RefSol    refSol(    3., 5., 4. );
    GivenData givenData( refSol );

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

    // Object to constrain the boundary 
    base::dof::constrainBoundary<FEBasis>( meshBoundary.begin(),
                                           meshBoundary.end(),
                                           mesh, field,
                                           boost::bind( &GivenData::dirichletBC<DoF>,
                                                        &givenData, _1, _2 ) );

    // Number of DoFs after constraint application!
    const std::size_t numDofs =
        base::dof::numberDoFsConsecutively( field.doFsBegin(), field.doFsEnd() );
    std::cout << "Number of dofs " << numDofs << std::endl;

    // Create a solver object
    typedef base::solver::Eigen3           Solver;
    Solver solver( numDofs );

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


    // Body force
    base::asmb::bodyForceComputation<FTB>( quadrature, solver, fieldBinder,
                                           boost::bind( &GivenData::forceFun,
                                                        &givenData, _1 ) );
#if 0
    base::asmb::bodyForceComputation2<FTB>( quadrature, solver, fieldBinder,
                                            boost::bind( &GivenData::forceFun2<Mesh::Element>,
                                                         &givenData, _1, _2 ) );
#endif 

    // Create a connectivity out of 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 );
    }


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

    // Neumann boundary condition
    base::asmb::neumannForceComputation<SFTB>( surfaceQuadrature, solver, surfaceFieldBinder,
                                               boost::bind( &GivenData::neumannBC,
                                                            &givenData,
                                                            _1, _2 ) );

    // compute stiffness matrix
    typedef heat::Laplace<FTB::Tuple> Laplace;
    Laplace laplace( 1. );
    base::asmb::stiffnessMatrixComputation<FTB>( quadrature, solver,
                                                 fieldBinder, laplace );
    
    // Finalise assembly
    solver.finishAssembly();

    // Solve
    solver.choleskySolve();

    // distribute results back to dofs
    base::dof::setDoFsFromSolver( solver, field );

    //--------------------------------------------------------------------------
    // output to a VTK file
    {
        // VTK Legacy
        const std::string vtkFile = baseName + ".vtk";
        std::ofstream vtk( vtkFile.c_str() );
        base::io::vtk::LegacyWriter vtkWriter( vtk );
        vtkWriter.writeUnstructuredGrid( mesh );
        base::io::vtk::writePointData( vtkWriter, mesh, field, "temperature" );

        const base::Vector<dim>::Type xi =
            base::ShapeCentroid<Mesh::Element::shape>::apply();
        base::io::vtk::writeCellData( vtkWriter, mesh, field,
                                      boost::bind(
                                          base::post::evaluateFieldGradient<
                                          Mesh::Element,
                                          Field::Element>, _1, _2, xi ),
                                      "flux" );
        vtk.close();
    }

    //--------------------------------------------------------------------------
    // compute L2-error
    std::cout << "L2-error = "
              << base::post::errorComputation<0>(
                  quadrature, mesh, field,
                  boost::bind( &ReferenceSolution<dim>::evaluate,
                               &refSol, _1 ) )
              << '\n';

    //--------------------------------------------------------------------------
    // compute H1-error
    std::cout << "H1-error = "
              << base::post::errorComputation<1>(
                  quadrature, mesh, field,
                  boost::bind( &ReferenceSolution<dim>::evaluateGradient,
                               &refSol, _1 ) )
              << '\n';

    //--------------------------------------------------------------------------
    // Compute mesh volume
    double volume = 0.;

    base::asmb::simplyIntegrate<FTB>( quadrature, volume, fieldBinder,
                                      base::kernel::Measure<FTB::Tuple>() );
    std::cout << "Volume of mesh: " << volume << '\n';

    
    return 0;
}
Exemple #26
0
bool
SMF::saveGrass()
{
	if( verbose )cout << "INFO: saveGrass\n";

	SMFEHGrass *grassHeader = NULL;
	for( unsigned int i = 0; i < extraHeaders.size(); ++i ) {
		if( extraHeaders[ i ]->type == 1 )
			grassHeader = reinterpret_cast<SMFEHGrass *>( extraHeaders[ i ] );
	}
	if( !grassHeader )return true;

	ImageBuf *imageBuf = NULL;
	ROI roi(	0, width * 16,
				0, length * 16,
				0, 1,
				0, 1);
	ImageSpec imageSpec(roi.xend, roi.yend, roi.chend, TypeDesc::UINT8 );

	if( is_smf(grassFile) ) {
		// Load from SMF
		SMF sourcesmf(grassFile);
		imageBuf = sourcesmf.getGrass();
	}
	if( !imageBuf ) {
		// Load image file
		imageBuf = new ImageBuf( grassFile );
		imageBuf->read( 0, 0, false, TypeDesc::UINT8 );
		if( imageBuf->initialized() ) {
			delete imageBuf;
			imageBuf = NULL;
		}
	}
	if( !imageBuf ) {
		// Generate blank
		imageBuf = new ImageBuf( "grass", imageSpec );
	}

	imageSpec = imageBuf->specmod();
	ImageBuf fixBuf;

	// Fix the number of channels
	if( imageSpec.nchannels != roi.chend ) {
		int map[] = {0};
		ImageBufAlgo::channels(fixBuf, *imageBuf, roi.chend, map );
		imageBuf->copy( fixBuf );
		fixBuf.clear();
	}

	// Fix the Dimensions
	if ( imageSpec.width != roi.xend || imageSpec.height != roi.yend ) {
		if( verbose )
			printf( "\tWARNING: %s is (%i,%i), wanted (%i, %i) Resampling.\n",
			typeFile.c_str(), imageSpec.width, imageSpec.height, roi.xend, roi.yend);
		ImageBufAlgo::resample(fixBuf, *imageBuf, false, roi);
		imageBuf->copy( fixBuf );
		fixBuf.clear();		
	}

	unsigned char *pixels = (unsigned char *)imageBuf->localpixels();

	char filename[256];
	sprintf( filename, "%s.smf", outPrefix.c_str() );

	if( verbose )printf( "    Source: %s.\n", grassFile.c_str() );

	fstream smf(filename, ios::binary | ios::in | ios::out);
	smf.seekp(grassHeader->grassPtr);

	smf.write( (char *)pixels, imageBuf->spec().image_bytes() );
	smf.close();
	
	delete imageBuf;
	if( is_smf( grassFile ) ) delete [] pixels;

	return false;
}
Exemple #27
0
//------------------------------------------------------------------------------
int main( int argc, char * argv[] )
{
    //--------------------------------------------------------------------------
    const unsigned    geomDeg   = 1;
    const unsigned    dim       = 2;
    // degrees of lowest-order TH element
    const unsigned    fieldDegU = 2; 
    const unsigned    fieldDegP = 1;

    const unsigned    tiOrder   = 1;
    typedef  base::time::BDF<tiOrder> MSM;
    
    const base::Shape shape     = base::SimplexShape<dim>::value;
    const base::Shape surfShape = base::SimplexShape<dim-1>::value;

    //--------------------------------------------------------------------------
    if ( argc != 2 ) {
        std::cout << "Usage:  " << argv[0] << " input.dat \n\n";
        return -1;
    }

    const std::string inputFile = boost::lexical_cast<std::string>( argv[1] );

    //--------------------------------------------------------------------------
    std::string meshFile, surfFile;
    double viscosity, density, tolerance, penaltyFactor, stepSize;
    unsigned maxIter, numSteps;
    {    
        //Feed properties parser with the variables to be read
        base::io::PropertiesParser prop;
        prop.registerPropertiesVar( "meshFile",         meshFile );
        prop.registerPropertiesVar( "surfFile",         surfFile );
        prop.registerPropertiesVar( "viscosity",        viscosity );
        prop.registerPropertiesVar( "density",          density );
        prop.registerPropertiesVar( "maxIter",          maxIter );
        prop.registerPropertiesVar( "tolerance",        tolerance );
        prop.registerPropertiesVar( "penaltyFactor",    penaltyFactor );
        prop.registerPropertiesVar( "stepSize",         stepSize );
        prop.registerPropertiesVar( "numSteps",         numSteps );

        // 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" );
        }
    }

    const std::string baseName = base::io::baseName( meshFile, ".smf" );

    //--------------------------------------------------------------------------
    typedef base::Unstructured<shape,geomDeg>     Mesh;

    Mesh mesh;
    {
        std::ifstream smf( meshFile.c_str() );
        VERIFY_MSG( smf.is_open(), "Cannot open mesh file" );
        base::io::smf::readMesh( smf, mesh );
        smf.close();
    }

    //--------------------------------------------------------------------------
    // Surface mesh
    typedef base::Unstructured<surfShape,1,dim>    SurfMesh;

    SurfMesh surfMesh;
    {
        std::ifstream smf( surfFile.c_str() );
        base::io::smf::readMesh( smf, surfMesh );
        smf.close();
    }

    //--------------------------------------------------------------------------
    // Compute the level set data
    typedef base::cut::LevelSet<dim> LevelSet;
    std::vector<LevelSet> levelSet;
    const bool isSigned = true;
    base::cut::bruteForce( mesh, surfMesh, isSigned, levelSet );

    const unsigned kernelDegEstimate = 5;

    //--------------------------------------------------------------------------
    // Make cut cell structure
    typedef base::cut::Cell<shape> Cell;
    std::vector<Cell> cells;
    base::cut::generateCutCells( mesh, levelSet, cells );

    // Quadrature 
    typedef base::cut::Quadrature<kernelDegEstimate,shape> CutQuadrature;
    CutQuadrature quadrature( cells, true );

    // for surface
    typedef base::SurfaceQuadrature<kernelDegEstimate,shape> SurfaceQuadrature;
    SurfaceQuadrature surfaceQuadrature;

    //------------------------------------------------------------------------------
    // Finite element bases
    const unsigned    nHist = MSM::numSteps;
    
    const unsigned    doFSizeU = dim;
    typedef base::fe::Basis<shape,fieldDegU>                FEBasisU;
    typedef base::cut::ScaledField<FEBasisU,doFSizeU,nHist> Velocity;
    Velocity velocity;
    base::dof::generate<FEBasisU>( mesh, velocity );
    
    const unsigned    doFSizeP = 1;
    typedef base::fe::Basis<shape,fieldDegP>                FEBasisP;
    typedef base::cut::ScaledField<FEBasisP,doFSizeP,nHist> Pressure;
    Pressure pressure;
    base::dof::generate<FEBasisP>( mesh, pressure );

    const unsigned    doFSizeS = dim;
    typedef base::fe::Basis<surfShape,1>              FEBasisS;
    typedef base::Field<FEBasisS,doFSizeS>            SurfField;
    SurfField surfVelocity, surfForces;
    base::dof::generate<FEBasisS>( surfMesh, surfVelocity );
    base::dof::generate<FEBasisS>( surfMesh, surfForces   );

    // set initial condition to the identity 
    base::dof::setField( surfMesh, surfVelocity,
                         boost::bind( &surfaceVelocity<dim,
                                      SurfField::DegreeOfFreedom>, _1, _2 ) );


    // boundary datum    
    base::cut::TransferSurfaceDatum<SurfMesh,SurfField,Mesh::Element>
        s2d( surfMesh, surfVelocity, levelSet );
    
    //--------------------------------------------------------------------------
    //  surface mesh
    typedef base::mesh::BoundaryMeshBinder<Mesh>::Type BoundaryMesh;
    BoundaryMesh boundaryMesh, immersedMesh;

    // from boundary
    {
        // identify list of element boundary faces
        base::mesh::MeshBoundary meshBoundary;
        meshBoundary.create( mesh.elementsBegin(), mesh.elementsEnd() );

        // generate a mesh from that list (with a filter)
        base::mesh::generateBoundaryMesh( meshBoundary.begin(),
                                          meshBoundary.end(),
                                          mesh, boundaryMesh,
                                          boost::bind( &boundaryFilter<dim>, _1 ) );

        // make a surface mesh from the implicit surface
        base::cut::generateSurfaceMesh<Mesh,Cell>( mesh, cells, immersedMesh );
    }

    // the composite field with geometry, velocity and pressure
    typedef base::asmb::FieldBinder<Mesh,Velocity,Pressure> Field;
    Field field( mesh, velocity, pressure );

    // define the system blocks (U,U), (U,P), and (P,U)
    typedef Field::TupleBinder<1,1,1>::Type TopLeft;
    typedef Field::TupleBinder<1,2>::Type   TopRight;
    typedef Field::TupleBinder<2,1>::Type   BotLeft;


    std::vector<double> supportsU, supportsP;
    std::size_t numDoFsU = std::distance( velocity.doFsBegin(), velocity.doFsEnd() );
    supportsU.resize( numDoFsU );
    std::size_t numDoFsP = std::distance( pressure.doFsBegin(), pressure.doFsEnd() );
    supportsP.resize( numDoFsP );

    base::cut::supportComputation( mesh, velocity, quadrature, supportsU );
    base::cut::supportComputation( mesh, pressure, quadrature, supportsP );

    velocity.scaleAndTagBasis( supportsU, 1.e-8 );
    pressure.scaleAndTagBasis( supportsP, 1.e-8 ); 
    //velocity.tagBasis( supportsU, 1.e-8 );
    //pressure.tagBasis( supportsP, 1.e-8 ); 

    // Fix one pressure dof
    // Pressure::DoFPtrIter pIter = pressure.doFsBegin();
    // std::advance( pIter, std::distance( pressure.doFsBegin(), pressure.doFsEnd() )/5 );
    // (*pIter) -> constrainValue( 0, 0.0 );

    // Number of DoFs after constraint application!
    numDoFsU =
        base::dof::numberDoFsConsecutively( velocity.doFsBegin(), velocity.doFsEnd() );
    std::cout << "# Number of velocity dofs " << numDoFsU << std::endl;

    numDoFsP =
        base::dof::numberDoFsConsecutively( pressure.doFsBegin(), pressure.doFsEnd(),
            numDoFsU );
    std::cout << "# Number of pressure dofs " << numDoFsP << std::endl;

    // kernels
    typedef fluid::StressDivergence<  TopLeft::Tuple>  StressDivergence;
    typedef fluid::Convection<        TopLeft::Tuple>  Convection;
    typedef fluid::PressureGradient<  TopRight::Tuple> GradP;
    typedef fluid::VelocityDivergence<BotLeft::Tuple>  DivU;

    StressDivergence stressDivergence( viscosity );
    Convection       convection(       density );
    GradP            gradP;
    DivU             divU( true );

    // for surface fields
    typedef base::asmb::SurfaceFieldBinder<BoundaryMesh,Velocity,Pressure> SurfaceFieldBinder;
    typedef SurfaceFieldBinder::TupleBinder<1,1,1>::Type STBUU;
    typedef SurfaceFieldBinder::TupleBinder<1,2  >::Type STBUP;
    SurfaceFieldBinder   boundaryFieldBinder(  boundaryMesh, velocity, pressure );
    SurfaceFieldBinder   immersedFieldBinder(  immersedMesh, velocity, pressure );

    std::ofstream forces( "forces.dat" );

    for ( unsigned step = 0; step < numSteps; step++ ) {

        const double time = step * stepSize;
        const double factor = ( time < 1.0 ? time : 1.0 );
    
        std::cout << step << ":  time=" << time << ", factor=" << factor
                  << "\n";

        //base::dof::clearDoFs( velocity );
        //base::dof::clearDoFs( pressure );
        
        //--------------------------------------------------------------------------
        // Nonlinear iterations
        unsigned iter = 0;
        while( iter < maxIter ) {

            // Create a solver object
            typedef base::solver::Eigen3           Solver;
            Solver solver( numDoFsU + numDoFsP );

            std::cout << "* Iteration " << iter << std::flush;

            // compute inertia terms, d/dt, due to time integration
            base::time::computeInertiaTerms<TopLeft,MSM>( quadrature, solver,
                                                          field, stepSize, step,
                                                          density );
    
            // Compute system matrix
            base::asmb::stiffnessMatrixComputation<TopLeft>( quadrature, solver,
                                                             field, stressDivergence );

            base::asmb::stiffnessMatrixComputation<TopLeft>( quadrature, solver,
                                                             field, convection );

            base::asmb::stiffnessMatrixComputation<TopRight>( quadrature, solver,
                                                              field, gradP );

            base::asmb::stiffnessMatrixComputation<BotLeft>( quadrature, solver,
                                                             field, divU );
            // compute residual forces
            base::asmb::computeResidualForces<TopLeft >( quadrature, solver, field,
                                                         stressDivergence );
            base::asmb::computeResidualForces<TopLeft >( quadrature, solver, field, convection );
            base::asmb::computeResidualForces<TopRight>( quadrature, solver, field, gradP );
            base::asmb::computeResidualForces<BotLeft >( quadrature, solver, field, divU );
        
            // Parameter classes
            base::nitsche::OuterBoundary ob( viscosity );
            base::nitsche::ImmersedBoundary<Cell> ib( viscosity, cells );

            // Penalty method
            base::nitsche::penaltyLHS<STBUU>( surfaceQuadrature, solver,
                                              boundaryFieldBinder, ob, penaltyFactor );
        
            base::nitsche::penaltyRHS<STBUU>( surfaceQuadrature, solver, boundaryFieldBinder, 
                                              boost::bind( &dirichlet<dim>, _1, factor),
                                              ob, penaltyFactor );

            base::nitsche::penaltyLHS<STBUU>( surfaceQuadrature, solver,
                                              immersedFieldBinder, ib, penaltyFactor );
        
            base::nitsche::penaltyRHS2<STBUU>( surfaceQuadrature, solver, immersedFieldBinder,
                                               s2d, ib, penaltyFactor );

            // Nitsche terms
            base::nitsche::primalEnergyLHS<STBUU>( stressDivergence, surfaceQuadrature, solver,
                                                   boundaryFieldBinder, ob );
            base::nitsche::dualEnergyLHS<STBUU>( stressDivergence, surfaceQuadrature, solver,
                                                 boundaryFieldBinder, ob );
            base::nitsche::energyRHS<STBUU>( stressDivergence, surfaceQuadrature, solver,
                                             boundaryFieldBinder,
                                             boost::bind( &dirichlet<dim>, _1, factor),
                                             ob );
        
            base::nitsche::primalEnergyLHS<STBUP>( gradP, surfaceQuadrature, solver,
                                                   boundaryFieldBinder, ob );
            base::nitsche::dualEnergyLHS<STBUP>( gradP, surfaceQuadrature, solver,
                                                 boundaryFieldBinder, ob );
         
            base::nitsche::energyRHS<STBUP>( gradP, surfaceQuadrature, solver,
                                             boundaryFieldBinder,
                                             boost::bind( &dirichlet<dim>, _1, factor), ob );

            base::nitsche::energyResidual<STBUU>( stressDivergence, surfaceQuadrature, solver,
                                                  boundaryFieldBinder, ob );
            
            base::nitsche::energyResidual<STBUP>( gradP, surfaceQuadrature, solver,
                                                  boundaryFieldBinder, ob );

            base::nitsche::primalEnergyLHS<STBUU>( stressDivergence, surfaceQuadrature, solver,
                                                   immersedFieldBinder, ib );
            base::nitsche::dualEnergyLHS<STBUU>( stressDivergence, surfaceQuadrature, solver,
                                                 immersedFieldBinder, ib );

            base::nitsche::energyRHS2<STBUU>( stressDivergence, surfaceQuadrature, solver,
                                              immersedFieldBinder, s2d, ib );
            
            base::nitsche::primalEnergyLHS<STBUP>( gradP, surfaceQuadrature, solver,
                                                   immersedFieldBinder, ib );
            base::nitsche::dualEnergyLHS<STBUP>( gradP, surfaceQuadrature, solver,
                                                 immersedFieldBinder, ib );

            base::nitsche::energyRHS2<STBUP>( gradP, surfaceQuadrature, solver,
                                              immersedFieldBinder, s2d, ib );

            base::nitsche::energyResidual<STBUU>( stressDivergence, surfaceQuadrature, solver,
                                                  immersedFieldBinder, ib );

            base::nitsche::energyResidual<STBUP>( gradP, surfaceQuadrature, solver,
                                                  immersedFieldBinder, ib );
        
            // Finalise assembly
            solver.finishAssembly();

            // check convergence via solver norms
            const double residualNorm = solver.norm();
            std::cout << " |R| = " << residualNorm << std::flush;

            if ( residualNorm < tolerance * viscosity) {
                std::cout << std::endl;
                break;
            }

            // Solve
            solver.superLUSolve();

            // distribute results back to dofs
            base::dof::addToDoFsFromSolver( solver, velocity );
            base::dof::addToDoFsFromSolver( solver, pressure );
            //base::dof::setDoFsFromSolver( solver, pressure );
        
            // check convergence via solver norms
            const double incrementNorm = solver.norm(0, numDoFsU );
            std::cout << " |dU| = " << incrementNorm << std::endl;

            // push history
            base::dof::pushHistory( velocity );
            base::dof::pushHistory( pressure );
        
            if ( incrementNorm < tolerance ) break;

            iter++;

        }

        writeVTKFile( baseName, step, mesh, velocity, pressure, levelSet, viscosity );
        {
            base::Vector<dim>::Type sumOfForces = base::constantVector<dim>( 0. );
            
            typedef Field::TupleBinder<1,2>::Type UP;
            //typedef fluid::Stress<UP::Tuple> Stress;
            //Stress stress( viscosity );
            typedef fluid::Traction<UP::Tuple> Traction;
            Traction traction( viscosity );
                
            base::cut::ComputeSurfaceForces<SurfMesh,SurfField,
                                            SurfaceQuadrature,STBUP::Tuple,Traction>
                computeSurfaceForces( surfMesh, surfForces, surfaceQuadrature, levelSet, traction );

            SurfaceFieldBinder::FieldIterator first = immersedFieldBinder.elementsBegin();
            SurfaceFieldBinder::FieldIterator  last = immersedFieldBinder.elementsEnd();
            for ( ; first != last; ++first ) {
                
                sumOfForces +=
                    computeSurfaceForces( STBUP::makeTuple( *first ) );
                
            }

            writeSurfaceVTKFile( baseName, step, surfMesh, surfVelocity, surfForces );


            std::cout << "  F= " << sumOfForces.transpose() << " \n";

            forces << time << " " << sumOfForces.transpose() << std::endl;;
        }

    }

    forces.close();

    return 0;
}
Exemple #28
0
//------------------------------------------------------------------------------
int main( int argc, char * argv[] )
{
    base::auxi::Timer total, detailed;
    
    //--------------------------------------------------------------------------
    // User input
    if ( argc != 5 ) {
        std::cout << "Usage:  " << argv[0]
                  << " file.smf radius E1 E2 \n\n";
        return -1;
    }

    // input mesh file
    const std::string smfFile  = boost::lexical_cast<std::string>( argv[1] );
    const std::string baseName = base::io::baseName( smfFile, ".smf" );

    // problem parameter
    const double radius = boost::lexical_cast<double>( argv[2] );
    const double E1     = boost::lexical_cast<double>( argv[3] );
    const double E2     = boost::lexical_cast<double>( argv[4] );

    const double penaltyFactor = 20.0;

    // material stuff
    const double nu = 0.3;
    const double lambda1 = mat::Lame::lambda( E1, nu );
    const double lambda2 = mat::Lame::lambda( E2, nu );
    const double mu1     = mat::Lame::mu( E1, nu );
    const double mu2     = mat::Lame::mu( E2, nu );

    //--------------------------------------------------------------------------
    const unsigned    geomDeg   = 1;
    const unsigned    dim       = SPACEDIM;
    const base::Shape shape     = base::SimplexShape<dim>::value;
    const bool        isSigned  = true;
    
    const unsigned fieldDeg = 1;
    const unsigned doFSize  = dim;

    // use Nitsche
    const bool useNitscheTerms = true;

    //--------------------------------------------------------------------------
    // Domain mesh
    typedef base::Unstructured<shape,geomDeg> Mesh;

    Mesh mesh;
    {
        std::ifstream smf( smfFile.c_str() );
        base::io::smf::readMesh( smf, mesh );
    }

    //--------------------------------------------------------------------------
    // Compute the level set data
    typedef base::cut::LevelSet<dim> LevelSet;
    std::vector<LevelSet> levelSet;
    base::cut::AnalyticSurface<dim>::Type as =
        boost::bind( &interface<dim>, _1, radius, _2 );
    base::cut::analyticLevelSet( mesh, as, isSigned, levelSet );


    //--------------------------------------------------------------------------
    // FE
    typedef base::fe::Basis<shape,fieldDeg>         FEBasis;
    typedef base::cut::ScaledField<FEBasis,doFSize> Field;
    Field fieldIn, fieldOut;

    base::dof::generate<FEBasis>( mesh, fieldIn  );
    base::dof::generate<FEBasis>( mesh, fieldOut );
    

    //--------------------------------------------------------------------------
    // Cut
    typedef base::cut::Cell<shape> Cell;
    std::vector<Cell> cells;
    base::cut::generateCutCells( mesh, levelSet, cells );

    //--------------------------------------------------------------------------
    //  surface meshes
    typedef base::cut::SurfaceMeshBinder<Mesh>::SurfaceMesh SurfaceMesh;
    SurfaceMesh boundaryMesh, interfaceMesh;

    // from boundary
    {
        // identify list of element boundary faces
        base::mesh::MeshBoundary meshBoundary;
        meshBoundary.create( mesh.elementsBegin(), mesh.elementsEnd() );

        // generate a mesh from that list (with a filter)
        base::mesh::generateBoundaryMesh( meshBoundary.begin(),
                                          meshBoundary.end(),
                                          mesh, boundaryMesh,
                                          boost::bind( &dirichletBoundary<dim>, _1 ) );
    }

    // from interface
    base::cut::generateSurfaceMesh<Mesh,Cell>( mesh, cells, interfaceMesh );

    //--------------------------------------------------------------------------
    // Quadratures
    const unsigned kernelDegEstimate = 5;
    // for domain
    typedef base::cut::Quadrature<kernelDegEstimate,shape> CutQuadrature;
    CutQuadrature cutQuadratureIn(  cells, true  );
    CutQuadrature cutQuadratureOut( cells, false );
    // for surface
    typedef base::SurfaceQuadrature<kernelDegEstimate,shape> SurfaceQuadrature;
    SurfaceQuadrature surfaceQuadrature;

    //--------------------------------------------------------------------------
    // Bind fields

    // for domain fields
    typedef base::asmb::FieldBinder<Mesh,Field,Field> FieldBinder;
    typedef FieldBinder::TupleBinder<1,1>::Type FTB1;
    typedef FieldBinder::TupleBinder<2,2>::Type FTB2;
    FieldBinder fieldBinder(  mesh, fieldIn, fieldOut );

    // for surface fields
    typedef base::asmb::SurfaceFieldBinder<SurfaceMesh,Field,Field> SurfaceFieldBinder;
    typedef SurfaceFieldBinder::TupleBinder<1,1>::Type STB11;
    typedef SurfaceFieldBinder::TupleBinder<2,2>::Type STB22;
    typedef SurfaceFieldBinder::TupleBinder<1,2>::Type STB12;
    typedef SurfaceFieldBinder::TupleBinder<2,1>::Type STB21;
    SurfaceFieldBinder   boundaryFieldBinder(  boundaryMesh, fieldIn, fieldOut );
    SurfaceFieldBinder interfaceFieldBinder(  interfaceMesh, fieldIn, fieldOut );

    // compute supports, scale basis
    const std::size_t numDoFs = std::distance( fieldIn.doFsBegin(), fieldIn.doFsEnd() );
    std::vector<double> supportsIn, supportsOut;
    supportsIn.resize(  numDoFs );
    supportsOut.resize( numDoFs );
    
    base::cut::supportComputation( mesh, fieldIn,  cutQuadratureIn,  supportsIn );
    base::cut::supportComputation( mesh, fieldOut, cutQuadratureOut, supportsOut );

    fieldIn.scaleAndTagBasis(  supportsIn,  1.e-10 );
    fieldOut.scaleAndTagBasis( supportsOut, 1.e-10 );
    //fieldIn.tagBasis( supportsIn, 1.e-10 );
    //fieldOut.tagBasis( supportsOut, 1.e-10 );
    
    // number DoFs, create solver
    const std::size_t activeDoFsIn = 
        base::dof::numberDoFsConsecutively( fieldIn.doFsBegin(), fieldIn.doFsEnd() );
    const std::size_t activeDoFsOut = 
        base::dof::numberDoFsConsecutively( fieldOut.doFsBegin(),
                                            fieldOut.doFsEnd(), activeDoFsIn );

    typedef base::solver::Eigen3 Solver;
    Solver solver( activeDoFsIn + activeDoFsOut );

    message( "Preprocessing time = " + detailed.print() );
    detailed.reset();
    

    //--------------------------------------------------------------------------
    // Stiffness matrix
    typedef mat::hypel::StVenant Material;
    Material material1( lambda1, mu1 );
    Material material2( lambda2, mu2 );

    // matrix kernel
    typedef solid::HyperElastic<Material,FTB1::Tuple> HyperElastic1;
    HyperElastic1 hyperElastic1( material1 );
    typedef solid::HyperElastic<Material,FTB2::Tuple> HyperElastic2;
    HyperElastic2 hyperElastic2( material2 );

    message( "Stiffness" );
    base::asmb::stiffnessMatrixComputation<FTB1>( cutQuadratureIn, solver,
                                                  fieldBinder, hyperElastic1 );
    base::asmb::stiffnessMatrixComputation<FTB2>( cutQuadratureOut, solver,
                                                  fieldBinder, hyperElastic2 );

    // boundary conditions
#if 1
    {
        message("Boundary Penalty");
        base::nitsche::OuterBoundary ob1( E1);
        base::nitsche::OuterBoundary ob2( E2);
        
        base::nitsche::penaltyLHS<STB11>( surfaceQuadrature, solver,
                                          boundaryFieldBinder, ob1, penaltyFactor );
        base::nitsche::penaltyLHS<STB22>( surfaceQuadrature, solver,
                                          boundaryFieldBinder, ob2, penaltyFactor );
        base::nitsche::penaltyRHS<STB11>( surfaceQuadrature, solver, boundaryFieldBinder, 
                                          boost::bind( &dirichlet<dim>, _1), ob1,
                                          penaltyFactor );
        base::nitsche::penaltyRHS<STB22>( surfaceQuadrature, solver, boundaryFieldBinder,
                                          boost::bind( &dirichlet<dim>, _1), ob2,
                                          penaltyFactor );

        if ( useNitscheTerms ) {
        
            message("Boundary Nitsche");
            base::nitsche::energyLHS<STB11>( hyperElastic1, surfaceQuadrature, solver,
                                             boundaryFieldBinder, ob1 );
            base::nitsche::energyLHS<STB22>( hyperElastic2, surfaceQuadrature, solver,
                                             boundaryFieldBinder, ob2 );

            base::nitsche::energyRHS<STB11>( hyperElastic1, surfaceQuadrature, solver,
                                             boundaryFieldBinder,
                                             boost::bind( &dirichlet<dim>, _1), ob1 );
            base::nitsche::energyRHS<STB22>( hyperElastic2, surfaceQuadrature, solver,
                                             boundaryFieldBinder,
                                             boost::bind( &dirichlet<dim>, _1), ob2 );
        }
        
    }

    // interface conditions
    {
        message("Interface Penalty");
        base::nitsche::ImmersedInterface<Cell> ip(  E1,  E2, cells );

        base::nitsche::penaltyLHS<STB11>( surfaceQuadrature, solver,
                                          interfaceFieldBinder, ip, penaltyFactor );
        base::nitsche::penaltyLHS<STB22>( surfaceQuadrature, solver,
                                          interfaceFieldBinder, ip, penaltyFactor );
        
        base::nitsche::penaltyLHS<STB12>( surfaceQuadrature, solver, interfaceFieldBinder,
                                          ip, -penaltyFactor );
        base::nitsche::penaltyLHS<STB21>( surfaceQuadrature, solver, interfaceFieldBinder,
                                          ip, -penaltyFactor );

        if ( useNitscheTerms ) {
            message("Interface Nitsche");
            
            base::nitsche::energyLHS<STB11>(
                hyperElastic1, surfaceQuadrature, solver,
                interfaceFieldBinder, ip, true, true  ); //  kappa1
        
            base::nitsche::energyLHS<STB21>(
                hyperElastic1, surfaceQuadrature, solver,
                interfaceFieldBinder, ip, true, false ); //  -kappa1
            
            base::nitsche::energyLHS<STB12>(
                hyperElastic2, surfaceQuadrature, solver,
                interfaceFieldBinder, ip, false, true );  //  kappa2
        
            base::nitsche::energyLHS<STB22>(
                hyperElastic2, surfaceQuadrature, solver,
                interfaceFieldBinder, ip, false, false ); // -kappa2
            
        }
    }
#endif
    
    //--------------------------------------------------------------------------
    // Solve and distribute
    solver.finishAssembly();

    message( "Assembly time = " + detailed.print() );
    detailed.reset();

#ifdef VERBOSE
    {
        solver.systemInfo( std::cout );

        std::ofstream mat( "matrix" );
        solver.debugLHS( mat );

        std::ofstream vec( "vector" );
        solver.debugRHS( vec );
    }
#endif

    
#if 1 // decide to solve and post-process

    
    //solver.choleskySolve();
    const unsigned numCGIter = solver.cgSolve();

    //message( "Solve time = " + detailed.print() );
    const double solveTime = detailed.seconds(); 
    detailed.reset();

    base::dof::setDoFsFromSolver( solver, fieldIn  );
    base::dof::setDoFsFromSolver( solver, fieldOut );


    //--------------------------------------------------------------------------
    // Extract distances, closestPoints and location flags from level set data
    {
    }
    
    //--------------------------------------------------------------------------
    {
        const std::string vtkFile = baseName + ".vtk";
        std::ofstream vtk( vtkFile.c_str() );
        base::io::vtk::LegacyWriter vtkWriter( vtk );

        vtkWriter.writeUnstructuredGrid( mesh );
        {
            std::vector<double> distances;
            std::transform( levelSet.begin(), levelSet.end(),
                            std::back_inserter( distances ),
                            boost::bind( &LevelSet::getSignedDistance, _1 ) );
            vtkWriter.writePointData( distances.begin(), distances.end(), "distances" );
        }
        
        {
            std::vector<bool>   location;
            std::transform( levelSet.begin(), levelSet.end(),
                            std::back_inserter( location ),
                            boost::bind( &LevelSet::isInterior, _1 ) );
            vtkWriter.writePointData( location.begin(), location.end(), "location" );
        }

        vtkWriter.writePointData( supportsIn.begin(),  supportsIn.end(),  "suppIn" );
        vtkWriter.writePointData( supportsOut.begin(), supportsOut.end(), "suppOut" );

        base::io::vtk::writePointData( vtkWriter, mesh, fieldIn,  "fieldIn"  );
        base::io::vtk::writePointData( vtkWriter, mesh, fieldOut, "fieldOut" );
        
        vtk.close();
    }

#ifdef VERBOSE   // decide error verbosity
    
    // integrate
    double volumeIn = 0.;
    base::asmb::simplyIntegrate<FTB1>( cutQuadratureIn, volumeIn, fieldBinder,
                                       base::kernel::Measure<FTB1::Tuple>() );


    double volumeOut = 0.;
    base::asmb::simplyIntegrate<FTB2>( cutQuadratureOut, volumeOut, fieldBinder,
                                      base::kernel::Measure<FTB2::Tuple>() );
    
    std::cout << "Volume of mesh: " << volumeIn << " + " << volumeOut
              << " = " << volumeIn + volumeOut
              << '\n';

    

#else
    // for convergence analysis
    std::cout << solveTime << "  " << numCGIter << "\n";
#endif


#endif // decide to solve and write

    message( "Post-process time = " + detailed.print() );
    message( "---------------------------------------" );
    
    message( "Total time = " + total.print() );
    
    return 0;
}
Exemple #29
0
/** Analysis of a CSG-modelled geometry (elasticity)
 */
int cutCell::csgElastic( int argc, char* argv[] )
{
    // spatial dimension
    const unsigned    dim = 3;
    typedef base::Vector<dim,double>::Type VecDim;

    //--------------------------------------------------------------------------
    // surfaces
    
    // sphere
    const double rs = 0.65;
    const VecDim cs = base::constantVector<dim>( 0.5 );
    base::cut::Sphere<dim> sphere( rs, cs, true );
    
    // cylinder
    const double rc = 0.3;
    const VecDim cc = cs;
    const VecDim zero =  base::constantVector<dim>(0.);
    VecDim e1 = zero; e1[0] = 1.;
    VecDim e2 = zero; e2[1] = 1.;
    VecDim e3 = zero; e3[2] = 1.;
    base::cut::Cylinder<dim> cyl1( rc, cc, e1, false );
    base::cut::Cylinder<dim> cyl2( rc, cc, e2, false );
    base::cut::Cylinder<dim> cyl3( rc, cc, e3, false );
    
    if ( argc != 3 ) {
        std::cerr << "Usage: " << argv[0] << " N  input.dat\n"
                  << "(Compiled for dim=" << dim << ")\n\n";
        return -1;
    }

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

    // read from input file
    double E, nu, xmax, cutThreshold, sX, sY, sZ;
    std::string meshFile;
    unsigned stabilise; // 0 - not, 1 - Höllig
    bool compute;
    unsigned maxIter, loadSteps;
    double tolerance, forceVal;
    {    
        //Feed properties parser with the variables to be read
        base::io::PropertiesParser prop;
        prop.registerPropertiesVar( "E",            E );
        prop.registerPropertiesVar( "nu",           nu );
        
        prop.registerPropertiesVar( "xmax",         xmax );

        prop.registerPropertiesVar( "sX",           sX );
        prop.registerPropertiesVar( "sY",           sY );
        prop.registerPropertiesVar( "sZ",           sZ );

        prop.registerPropertiesVar( "stabilise",    stabilise );
        prop.registerPropertiesVar( "meshFile",     meshFile );
        prop.registerPropertiesVar( "compute",      compute );
        prop.registerPropertiesVar( "cutThreshold", cutThreshold );

        prop.registerPropertiesVar( "maxIter",      maxIter );
        prop.registerPropertiesVar( "tolerance",    tolerance );
        prop.registerPropertiesVar( "loadSteps",    loadSteps );
        prop.registerPropertiesVar( "forceVal",     forceVal );
        
        // Read variables from the input file
        std::ifstream inp( inputFile.c_str()  );
        VERIFY_MSG( inp.is_open(), "Cannot open input file" );
        VERIFY_MSG( prop.readValuesAndCheck( inp ), "Input error" );
        inp.close( );
    }

    // in case of no computation, do not stabilise
    if ( not compute ) stabilise = 0;
    
    // basic attributes of the computation
    const unsigned             geomDeg  = 1;
    const unsigned             fieldDeg = 1;
    const base::Shape             shape = //base::SimplexShape<dim>::value;
        base::HyperCubeShape<dim>::value;
    const base::Shape surfShape = base::SimplexShape<dim-1>::value;
    const unsigned    kernelDegEstimate = 5;

    // Bulk mesh
    typedef base::Unstructured<shape,geomDeg>  Mesh;
    typedef Mesh::Node::VecDim VecDim;
    Mesh mesh;
    std::string baseName;

    VecDim a, b;
    for ( unsigned d = 0; d < dim; d++ ) {
        a[d] = 0.;
        b[d] = xmax;
    }
    base::auxi::BoundingBox<dim> bbox( a, b );
    
    if ( numElements > 0 ) {
        base::Vector<dim,unsigned>::Type N;
        for ( unsigned d = 0; d < dim; d++ ) {
            N[d] = numElements;
        }
        generateMesh<dim>( mesh, N, a, b );

        baseName = argv[0] + std::string(".") + base::io::leadingZeros( numElements );
    }
    else{
        std::ifstream smf( meshFile.c_str() );
        base::io::smf::readMesh( smf, mesh );

        baseName = base::io::baseName( meshFile, ".smf" );
    }

    // Boundary mesh
    typedef base::mesh::BoundaryMeshBinder<Mesh,true>::Type BoundaryMesh;
    BoundaryMesh boundaryMesh;
    base::mesh::MeshBoundary meshBoundary;
    meshBoundary.create( mesh.elementsBegin(), mesh.elementsEnd() );
    base::mesh::generateBoundaryMesh( meshBoundary.begin(), meshBoundary.end(),
                                      mesh, boundaryMesh );

    // Cell structures
    typedef base::cut::Cell<shape> Cell;
    std::vector<Cell> cells;

    typedef base::cut::Cell<surfShape> SurfCell;
    std::vector<SurfCell> surfCells;

    // intersection of all level sets
    typedef base::cut::LevelSet<dim> LevelSet;
    std::vector<LevelSet> levelSetIntersection;

    //--------------------------------------------------------------------------
    // go through immersed surfaces
    //ImplicitGeometry<Mesh> geometry( mesh, boundaryMesh, sphere );
    cutCell::ImplicitGeometry<Mesh> geometry( mesh, boundaryMesh );
    geometry.intersectAnalytical( sphere, cutThreshold );
    geometry.intersectAnalytical( cyl1, cutThreshold );
    geometry.intersectAnalytical( cyl2, cutThreshold );
    geometry.intersectAnalytical( cyl3, cutThreshold );

    levelSetIntersection = geometry.getLevelSet();

#ifdef EMBEDFIRST
    cells                = geometry.getCells();
    surfCells            = geometry.getSurfCells();
#else
    base::cut::generateCutCells( mesh,         levelSetIntersection, cells,
                                 base::cut::CREATE );
    base::cut::generateCutCells( boundaryMesh, levelSetIntersection, surfCells,
                                 base::cut::CREATE );
#endif

    // Generate a mesh from the immersed surface
    typedef base::cut::SurfaceMeshBinder<Mesh>::SurfaceMesh SurfaceMesh;
    SurfaceMesh surfaceMesh;
    base::cut::generateSurfaceMesh<Mesh,Cell>( mesh, cells, surfaceMesh );

    //--------------------------------------------------------------------------
    // FE
#ifdef LINEAR
    typedef mat::hypel::StVenant               Material;
#else
    typedef mat::hypel::NeoHookeanCompressible Material;
#endif
    
    typedef cutCell::HyperElastic<Mesh,Material,fieldDeg> HyperElastic;
    HyperElastic hyperElastic( mesh, E, nu );

    typedef cutCell::SurfaceField<SurfaceMesh,HyperElastic::Field> SurfaceField;
    SurfaceField surfaceField(      surfaceMesh,         hyperElastic.getField() );
    SurfaceField boundaryField(     boundaryMesh,        hyperElastic.getField() );

    //--------------------------------------------------------------------------
    // Quadratures
    typedef base::cut::Quadrature<kernelDegEstimate,shape> CutQuadrature;
    CutQuadrature cutQuadrature( cells, true );

    typedef base::Quadrature<kernelDegEstimate,surfShape> SurfaceQuadrature;
    SurfaceQuadrature surfaceQuadrature;

    typedef base::cut::Quadrature<kernelDegEstimate,surfShape> SurfaceCutQuadrature;
    SurfaceCutQuadrature surfaceCutQuadrature( surfCells, true );

    // compute supports
    const std::size_t numDoFs = std::distance( hyperElastic.getField().doFsBegin(),
                                               hyperElastic.getField().doFsEnd() );
    std::vector<double> supports;
    supports.resize(  numDoFs );
    
    base::cut::supportComputation( mesh, hyperElastic.getField(), cutQuadrature,  supports );
    std::vector<std::pair<std::size_t,VecDim> > doFLocation;
    base::dof::associateLocation( hyperElastic.getField(), doFLocation );

    // Fundamental solution
#ifdef LINEAR
    HyperElastic::VecDim sourcePoint = base::constantVector<dim>( 0. );
    HyperElastic::VecDim pointForce  = base::constantVector<dim>( 0. );
    sourcePoint[0] = sX; pointForce[0] = 1.;
    if ( dim > 1 ) { sourcePoint[1] = sY; pointForce[1] = 2.; }
    if ( dim > 2 ) { sourcePoint[2] = sZ; pointForce[2] = 3.; }

    typedef base::auxi::FundSolElastoStatic<dim> FSol;
    FSol fSol( mat::Lame::lambda( E, nu ), mat::Lame::mu( E, nu ) );

    typedef boost::function< HyperElastic::VecDoF( const VecDim& ) > FFun;
    FFun fFun = boost::bind( &FSol::fun, &fSol, _1, sourcePoint, pointForce );
    
    // apply dirichlet constraints
    base::dof::constrainBoundary<HyperElastic::FEBasis>(
        meshBoundary.begin(), meshBoundary.end(),
        mesh, hyperElastic.getField(), 
        boost::bind( &dirichletBCFromFSol<FFun,HyperElastic::DoF>, _1, _2, fFun ) );

    typedef boost::function< HyperElastic::VecDoF( const VecDim&,
                                                   const VecDim&) > FFun2;
    FFun2 fFun2 = boost::bind( &FSol::coNormal, &fSol, _1, sourcePoint, pointForce, _2 );
    
#else
    
    base::dof::constrainBoundary<HyperElastic::FEBasis>(
        meshBoundary.begin(), meshBoundary.end(),
        mesh, hyperElastic.getField(), 
        boost::bind( &fixBottom<dim,HyperElastic::DoF>, _1, _2, bbox ) );
    
#endif

    base::cut::stabiliseBasis( mesh, hyperElastic.getField(), supports, doFLocation );

    // number DoFs
    const std::size_t activeDoFsU = 
        base::dof::numberDoFsConsecutively( hyperElastic.getField().doFsBegin(),
                                            hyperElastic.getField().doFsEnd() );

    //--------------------------------------------------------------------------
    // Load step loop
#ifdef LINEAR
    const unsigned numSteps = 1;
    const unsigned numIter  = 1;
#else
    const unsigned numSteps = loadSteps;
    const unsigned numIter  = maxIter;

    // write zero state 
    hyperElastic.writeVTKFile(    baseName, 0, levelSetIntersection, cells, true );
    hyperElastic.writeVTKFileCut( baseName, 0, levelSetIntersection, cells, true );
#endif

    for ( unsigned s = 0; s < numSteps and compute; s++ ) {

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

            // Create a solver object
            typedef base::solver::Eigen3           Solver;
            Solver solver( activeDoFsU );

#ifdef LINEAR            
            // Neumann boundary condition -- box boundary
            boundaryField.applyNeumannBoundaryConditions( surfaceCutQuadrature,
                                                          solver, fFun2 );
        
            // Neumann boundary condition -- immersed surface
            surfaceField.applyNeumannBoundaryConditions( surfaceQuadrature,
                                                         solver, fFun2 );
            
#else
            const double factor =
                static_cast<double>( s+1 ) / static_cast<double>( numSteps );
            
            boundaryField.applyNeumannBoundaryConditions(
                surfaceCutQuadrature,
                solver,
                boost::bind( &twistTop<dim>, _1, _2, bbox, forceVal * factor ) );

            
#endif
        
            hyperElastic.assembleBulk( cutQuadrature, solver, iter );
            
            // Finalise assembly
            solver.finishAssembly();

            // norm of residual 
            const double conv1 = solver.norm();
#ifndef LINEAR
            std::cout << s << "  " << iter << "  " << conv1 << "  ";
#endif
            // convergence via residual norm
            if ( conv1 < tolerance * E ) { // note the tolerance multiplier
#ifndef LINEAR
                std::cout << std::endl;
#endif
                break;
            }

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

            // norm of displacement increment
            const double conv2 = solver.norm();
#ifndef LINEAR
            std::cout << conv2 << std::endl;
#endif
            iter++;
            
            // convergence via increment
            if ( conv2 < tolerance ) break;
            
        } // end iterations
            

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

        //----------------------------------------------------------------------
        // write a vtk file
        hyperElastic.writeVTKFile(    baseName, s+1, levelSetIntersection, cells );
        hyperElastic.writeVTKFileCut( baseName, s+1, levelSetIntersection, cells );
        
    } // end load steps

    //------------------------------------------------------------------------------
    // Compute error and mesh volume for convergence (linear only)
#ifdef LINEAR            
    double hmin;
    {
        std::vector<double> h;
        Mesh::ElementPtrConstIter eIter = mesh.elementsBegin();
        Mesh::ElementPtrConstIter eEnd  = mesh.elementsEnd();
        for ( ; eIter != eEnd; ++eIter )  {
            h.push_back( base::mesh::elementSize( *eIter ) );
        }
     
        hmin = *std::min_element( h.begin(), h.end() );
    }

    std::cout << hmin << "  ";
    
    //--------------------------------------------------------------------------
    // Error
    std::cout << hyperElastic.computeL2Error( cutQuadrature, fFun ) << "  ";
    
    //--------------------------------------------------------------------------
    // Compute mesh volume
    const double volume = hyperElastic.computeVolume( cutQuadrature );
    std::cout << std::abs(volume-exactV) << "  ";

    //--------------------------------------------------------------------------
    // Compute surface area
    double area = surfaceField.computeArea( surfaceQuadrature );
    area += boundaryField.computeArea( surfaceCutQuadrature );
        
    std::cout << std::abs(area-exactA) << "  " << std::endl;

#endif

    return 0;
}
Exemple #30
0
bool
SMF::save()
{
	char filename[256];
	sprintf( filename, "%s.smf", outPrefix.c_str() );
	ofstream smf(filename, ios::binary | ios::out);
	if( verbose )printf( "\nINFO: Saving %s.\n", filename );

	char magic[] = "spring map file\0";
	smf.write( magic, 16 );

	int version = 1;
	smf.write( (char *)&version, 4);
	if( verbose )printf( "\tVersion: %i.\n", version );

	int id = rand();
	smf.write( (char *)&id, 4);
	if( verbose )printf( "\tMapID: %i.\n", id );

	int width = this->width * 64;
	smf.write( (char *)&width, 4);
	if( verbose )printf( "\tWidth: %i.\n", width );

	int length = this->length * 64;
	smf.write( (char *)&length, 4);
	if( verbose )printf( "\tLength: %i.\n", length );

	int squareWidth = 8;
	smf.write( (char *)&squareWidth, 4);
	if( verbose )printf( "\tSquareWidth: %i.\n", squareWidth );

	int squareTexels = 8;
	smf.write( (char *)&squareTexels, 4);
	if( verbose )printf( "\tSquareTexels: %i.\n", squareTexels );

	int tileTexels = 32;
	smf.write( (char *)&tileTexels, 4);
	if( verbose )printf( "\tTileTexels: %i.\n", tileTexels );

	float floor = this->floor * 512;
	smf.write( (char *)&floor, 4);
	if( verbose )printf( "\tMinHeight: %0.2f.\n", floor );

	float ceiling = this->ceiling * 512;
	smf.write( (char *)&ceiling, 4);
	if( verbose )printf( "\tMaxHeight: %0.2f.\n", ceiling );

	smf.write( (char *)&heightPtr, 4);
	if( verbose )printf( "\tHeightPtr: %i.\n", heightPtr );
	smf.write( (char *)&typePtr, 4);
	if( verbose )printf( "\tTypePtr: %i.\n", typePtr );
	smf.write( (char *)&tilesPtr, 4);
	if( verbose )printf( "\tTilesPtr: %i.\n", tilesPtr );
	smf.write( (char *)&minimapPtr, 4);
	if( verbose )printf( "\tMinimapPtr: %i.\n", minimapPtr );
	smf.write( (char *)&metalPtr, 4);
	if( verbose )printf( "\tMetalPtr: %i.\n", metalPtr );
	smf.write( (char *)&featuresPtr, 4);
	if( verbose )printf( "\tFeaturesPtr: %i.\n", featuresPtr );

	int nExtraHeaders = extraHeaders.size();
	smf.write( (char *)&nExtraHeaders, 4);
	if( verbose )printf( "\tExtraHeaders: %i.\n", nExtraHeaders );

	if(verbose) printf( "    Extra Headers:\n");
	for( unsigned int i = 0; i < extraHeaders.size(); ++i ) {
		smf.write((char *)extraHeaders[i], extraHeaders[i]->size);
		if( verbose ) {
			if(extraHeaders[i]->type == 1)
				printf("\tGrassPtr: %i.\n",
				((SMFEHGrass *)extraHeaders[i])->grassPtr );
			else printf( "\t Unknown Header\n");
		}
	}
	
	smf.close();

	saveHeight();
	saveType();
	saveMinimap();
	saveMetal();

	for( unsigned int i = 0; i < extraHeaders.size(); ++i ) {
		if(extraHeaders[i]->type == 1)saveGrass();
	}

	saveTilemap();
	saveFeatures();

	return false;
}