<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome_frame/test/net/test_automation_provider.h"

#include "base/command_line.h"
#include "chrome/test/automation/automation_messages.h"

#include "chrome_frame/test/net/test_automation_resource_message_filter.h"

namespace {

// A special command line switch to just run the unit tests without CF in
// the picture.  Can be useful when the harness itself needs to be debugged.
const wchar_t kNoCfTestRun[] = L"no-cf-test-run";

bool CFTestsDisabled() {
  static bool switch_present = CommandLine::ForCurrentProcess()->
      HasSwitch(kNoCfTestRun);
  return switch_present;
}

}  // end namespace

TestAutomationProvider* TestAutomationProvider::g_provider_instance_ = NULL;

TestAutomationProvider::TestAutomationProvider(
    Profile* profile,
    TestAutomationProviderDelegate* delegate)
    : AutomationProvider(profile), tab_handle_(-1), delegate_(delegate) {
  filter_ = new TestAutomationResourceMessageFilter(this);
  URLRequest::RegisterProtocolFactory("http",
                                      TestAutomationProvider::Factory);
  URLRequest::RegisterProtocolFactory("https",
                                      TestAutomationProvider::Factory);
  g_provider_instance_ = this;
}

TestAutomationProvider::~TestAutomationProvider() {
  g_provider_instance_ = NULL;
}

void TestAutomationProvider::OnMessageReceived(const IPC::Message& msg) {
  if (filter_->OnMessageReceived(msg))
    return;  // Message handled by the filter.

  __super::OnMessageReceived(msg);
}

// IPC override to grab the tab handle.
bool TestAutomationProvider::Send(IPC::Message* msg) {
  if (msg->type() == AutomationMsg_TabLoaded::ID) {
    DCHECK(tab_handle_ == -1) << "Currently only support one tab";
    void* iter = NULL;
    CHECK(msg->ReadInt(&iter, &tab_handle_));
    DLOG(INFO) << "Got tab handle: " << tab_handle_;
    DCHECK(tab_handle_ != -1 && tab_handle_ != 0);
    delegate_->OnInitialTabLoaded();
  }

  return AutomationProvider::Send(msg);
}

URLRequestJob* TestAutomationProvider::Factory(URLRequest* request,
                                               const std::string& scheme) {
  if (CFTestsDisabled())
    return NULL;

  if (request->url().SchemeIs("http") || request->url().SchemeIs("https")) {
    // Only look at requests that don't have any user data.
    // ResourceDispatcherHost uses the user data for requests that it manages.
    // We don't want to mess with those.

    // We could also check if the current thread is our TestUrlRequest thread
    // and only intercept requests that belong to that thread.
    if (g_provider_instance_ && request->GetUserData(NULL) == NULL &&
        g_provider_instance_->tab_handle_ != -1) {
      // We generate our own request id which is also what
      // ResourceDispatcherHost does (well, the id is actually generated by
      // ResourceDispatcher).  Since these requests are divided into with
      // and without userdata, we're OK.  However, just to make debugging
      // a little easier, we have a significantly higher start value.
      static int new_id = 0x00100000;
      URLRequestAutomationJob* job = new URLRequestAutomationJob(request,
          g_provider_instance_->tab_handle_, new_id++,
          g_provider_instance_->filter_, false);
      return job;
    }
  }

  return NULL;
}

// static
TestAutomationProvider* TestAutomationProvider::NewAutomationProvider(
    Profile* p, const std::string& channel,
    TestAutomationProviderDelegate* delegate) {
  TestAutomationProvider* automation = new TestAutomationProvider(p, delegate);
  automation->ConnectToChannel(channel);
  automation->SetExpectedTabCount(1);
  return automation;
}
<commit_msg>Attempt 2 at fixing the chrome frame net tests hang on the builders. This hang occurs because of a race condition in registering the http/https protocol factories. The net tests registers a protocol factory and the Chrome AutomationResourceMessageFilter also registers factories. If the net tests ends up being first in the chain then the requests are incorrectly dropped.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome_frame/test/net/test_automation_provider.h"

#include "base/command_line.h"
#include "chrome/test/automation/automation_messages.h"

#include "chrome_frame/test/net/test_automation_resource_message_filter.h"

namespace {

// A special command line switch to just run the unit tests without CF in
// the picture.  Can be useful when the harness itself needs to be debugged.
const wchar_t kNoCfTestRun[] = L"no-cf-test-run";

bool CFTestsDisabled() {
  static bool switch_present = CommandLine::ForCurrentProcess()->
      HasSwitch(kNoCfTestRun);
  return switch_present;
}

}  // end namespace

TestAutomationProvider* TestAutomationProvider::g_provider_instance_ = NULL;

TestAutomationProvider::TestAutomationProvider(
    Profile* profile,
    TestAutomationProviderDelegate* delegate)
    : AutomationProvider(profile), tab_handle_(-1), delegate_(delegate) {
  // We need to register the protocol factory before the
  // AutomationResourceMessageFilter registers the automation job factory to
  // ensure that we don't inadvarently end up handling http requests which
  // we don't expect. The initial chrome frame page for the network tests
  // issues http requests which our test factory should not handle.
  URLRequest::RegisterProtocolFactory("http",
                                      TestAutomationProvider::Factory);
  URLRequest::RegisterProtocolFactory("https",
                                      TestAutomationProvider::Factory);
  filter_ = new TestAutomationResourceMessageFilter(this);
  g_provider_instance_ = this;
}

TestAutomationProvider::~TestAutomationProvider() {
  g_provider_instance_ = NULL;
}

void TestAutomationProvider::OnMessageReceived(const IPC::Message& msg) {
  if (filter_->OnMessageReceived(msg))
    return;  // Message handled by the filter.

  __super::OnMessageReceived(msg);
}

// IPC override to grab the tab handle.
bool TestAutomationProvider::Send(IPC::Message* msg) {
  if (msg->type() == AutomationMsg_TabLoaded::ID) {
    DCHECK(tab_handle_ == -1) << "Currently only support one tab";
    void* iter = NULL;
    CHECK(msg->ReadInt(&iter, &tab_handle_));
    DLOG(INFO) << "Got tab handle: " << tab_handle_;
    DCHECK(tab_handle_ != -1 && tab_handle_ != 0);
    delegate_->OnInitialTabLoaded();
  }

  return AutomationProvider::Send(msg);
}

URLRequestJob* TestAutomationProvider::Factory(URLRequest* request,
                                               const std::string& scheme) {
  if (CFTestsDisabled())
    return NULL;

  if (request->url().SchemeIs("http") || request->url().SchemeIs("https")) {
    // Only look at requests that don't have any user data.
    // ResourceDispatcherHost uses the user data for requests that it manages.
    // We don't want to mess with those.

    // We could also check if the current thread is our TestUrlRequest thread
    // and only intercept requests that belong to that thread.
    if (g_provider_instance_ && request->GetUserData(NULL) == NULL &&
        g_provider_instance_->tab_handle_ != -1) {
      // We generate our own request id which is also what
      // ResourceDispatcherHost does (well, the id is actually generated by
      // ResourceDispatcher).  Since these requests are divided into with
      // and without userdata, we're OK.  However, just to make debugging
      // a little easier, we have a significantly higher start value.
      static int new_id = 0x00100000;
      URLRequestAutomationJob* job = new URLRequestAutomationJob(request,
          g_provider_instance_->tab_handle_, new_id++,
          g_provider_instance_->filter_, false);
      return job;
    }
  }

  return NULL;
}

// static
TestAutomationProvider* TestAutomationProvider::NewAutomationProvider(
    Profile* p, const std::string& channel,
    TestAutomationProviderDelegate* delegate) {
  TestAutomationProvider* automation = new TestAutomationProvider(p, delegate);
  automation->ConnectToChannel(channel);
  automation->SetExpectedTabCount(1);
  return automation;
}
<|endoftext|>


<commit_before>#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"
#include "cinder/ip/Fill.h"

using namespace ci;
using namespace ci::app;
using namespace std;

class TextureUploadApp : public App {
  public:
	static void prepareSettings( Settings *settings ) { settings->setMultiTouchEnabled( false ); }
	void setup();
	template<typename T>
	void setupTexConstructor();
	template<typename T>
	void setupTexUpdate();

	template<typename T>
	void setupVoidStarConstructor( int64_t maxV );

	void mouseDown( MouseEvent event ) override;
	void draw() override;

	gl::TextureRef		mCurTex;
	ImageSourceRef		mImg, mImg2, mImgAlpha, mImg2Alpha;

	template<typename T>
	gl::TextureRef genTexConstructor( bool color, bool alpha );
	template<typename T>
	gl::TextureRef genTexUpdate( bool color, bool alpha );

	size_t										mCurFnIdx;
	vector<function<gl::TextureRef(void)>>		mTexGenFns;
};

template<typename T>
gl::TextureRef TextureUploadApp::genTexConstructor( bool color, bool alpha )
{
	if( color && alpha ) {
		SurfaceT<T> s( mImgAlpha );
		return gl::Texture::create( s );
	}
	else if( color ) {
		SurfaceT<T> s( mImg );
		return gl::Texture::create( s );
	}
	else { // grayscale
		ChannelT<T> s( mImg );
		return gl::Texture::create( s );
	}
}

template<typename T>
gl::TextureRef TextureUploadApp::genTexUpdate( bool color, bool alpha )
{
	if( color && alpha ) {
		SurfaceT<T> s0( mImgAlpha );
		gl::TextureRef result = gl::Texture::create( s0 );
		result->update( SurfaceT<T>( mImg2Alpha ) );
		return result;
	}
	else if( color ) {
		SurfaceT<T> s0( mImg );
		gl::TextureRef result = gl::Texture::create( s0 );
		result->update( SurfaceT<T>( mImg2 ) );
		return result;
	}
	else { // grayscale
		ChannelT<T> s0( mImg );
		gl::TextureRef result = gl::Texture::create( s0 );
		result->update( ChannelT<T>( mImg2 ) );
		return result;
	}
}

template<typename T>
void TextureUploadApp::setupTexConstructor()
{
	mTexGenFns.push_back( [=](void)->gl::TextureRef {
			app::console() << "Constructor Surface RGB " << sizeof(T) * 8 << "-bit" << std::endl;
			return genTexConstructor<T>( true, false );
		}
	);

	mTexGenFns.push_back( [=](void)->gl::TextureRef {
			app::console() << "Constructor Surface RGBA " << sizeof(T) * 8 << "-bit" << std::endl;
			return genTexConstructor<T>( true, true );
		}
	);

	mTexGenFns.push_back( [=](void)->gl::TextureRef {
			app::console() << "Constructor Channel " << sizeof(T) * 8 << "-bit" << std::endl;
			return genTexConstructor<T>( false, false );
		}
	);
}

template<typename T>
void TextureUploadApp::setupTexUpdate()
{
	mTexGenFns.push_back( [=](void)->gl::TextureRef {
			app::console() << "Update Surface RGB " << sizeof(T) * 8 << "-bit" << std::endl;
			return genTexUpdate<T>( true, false );
		}
	);

	mTexGenFns.push_back( [=](void)->gl::TextureRef {
			app::console() << "Update Surface RGBA " << sizeof(T) * 8 << "-bit" << std::endl;
			return genTexUpdate<T>( true, true );
		}
	);

	mTexGenFns.push_back( [=](void)->gl::TextureRef {
			app::console() << "Update Channel " << sizeof(T) * 8 << "-bit" << std::endl;
			return genTexUpdate<T>( false, false );
		}
	);

	mTexGenFns.push_back( [=](void)->gl::TextureRef {
			app::console() << "Update Subregion RGB " << sizeof(T) * 8 << "-bit" << std::endl;
			SurfaceT<T> srcImg( mImg );
			SurfaceT<T> square( 100, 100, false );
			gl::TextureRef result = gl::Texture::create( mImg2 );
			square.copyFrom( srcImg, Area( 28, 128, 28 + 100, 128 + 100 ), ivec2( -28, -128 ) );
			for( int y = 0; y < result->getHeight() / square.getHeight(); y += 2 ) {
				for( int x = y%2; x < result->getWidth() / square.getWidth(); x += 2 ) {
					result->update( square, 0, ivec2( x * square.getWidth(), y * square.getHeight() ) );
				}
			}
			return result;
		}
	);

	mTexGenFns.push_back( [=](void)->gl::TextureRef {
			app::console() << "Update Subregion Channel " << sizeof(T) * 8 << "-bit" << std::endl;
			ChannelT<T> srcImg( mImg );
			ChannelT<T> square( 100, 100 );
			gl::TextureRef result = gl::Texture::create( ChannelT<T>( mImg2 ) );
			square.copyFrom( srcImg, Area( 28, 128, 28 + 100, 128 + 100 ), ivec2( -28, -128 ) );
			for( int y = 0; y < result->getHeight() / square.getHeight(); y += 2 ) {
				for( int x = y%2; x < result->getWidth() / square.getWidth(); x += 2 ) {
					result->update( square, 0, ivec2( x * square.getWidth(), y * square.getHeight() ) );
				}
			}
			return result;
		}
	);
}

// This is for the constructor variant that accepts a void* to data, rather than a Surface/Channel
template<typename T>
void TextureUploadApp::setupVoidStarConstructor( int64_t maxV )
{
	GLenum dataType;
	if( std::is_same<T,uint8_t>::value )
		dataType = GL_UNSIGNED_BYTE;
	else if( std::is_same<T,int16_t>::value )
		dataType = GL_SHORT;
	else if( std::is_same<T,int32_t>::value )
		dataType = GL_INT;
	else if( std::is_same<T,uint32_t>::value )
		dataType = GL_UNSIGNED_INT;
	else
		throw;

	mTexGenFns.push_back( [=](void)->gl::TextureRef {
			app::console() << "void* Constructor: " << typeid(T).name() << sizeof(T) * 8 << "-bit" << std::endl;
			Surface8u temp( mImg );
			std::unique_ptr<T[]> data( new T[mImg->getWidth() * mImg->getHeight() * 3] );

			for( int y = 0; y < temp.getHeight(); ++y ) {
				for( int x = 0; x < temp.getWidth(); ++x ) {
					ColorA8u color = temp.getPixel( ivec2( x, y ) );
					data[(y*temp.getWidth()+x)*3 + 0] = color.r / 255.0f * maxV;
					data[(y*temp.getWidth()+x)*3 + 1] = color.g / 255.0f * maxV;
					data[(y*temp.getWidth()+x)*3 + 2] = color.b / 255.0f * maxV;
				}
			}
			gl::TextureRef result = gl::Texture::create( data.get(), GL_RGB, temp.getWidth(), temp.getHeight(),
											gl::Texture2d::Format().dataType( dataType ).internalFormat( GL_RGB ) );
			result->setTopDown( true );

			return result;
		}
	);

	mTexGenFns.push_back( [=](void)->gl::TextureRef {
			app::console() << "void* update: " << typeid(T).name() << sizeof(T) * 8 << "-bit" << std::endl;
			Surface8u temp( mImg );
			Surface8u temp2( mImg2 );
			std::unique_ptr<T[]> data( new T[mImg2->getWidth() * mImg2->getHeight() * 3] );

			for( int y = 0; y < temp2.getHeight(); ++y ) {
				for( int x = 0; x < temp2.getWidth(); ++x ) {
					ColorA8u color = temp2.getPixel( ivec2( x, y ) );
					data[(y*temp2.getWidth()+x)*3 + 0] = color.r / 255.0f * maxV;
					data[(y*temp2.getWidth()+x)*3 + 1] = color.g / 255.0f * maxV;
					data[(y*temp2.getWidth()+x)*3 + 2] = color.b / 255.0f * maxV;
				}
			}

			gl::TextureRef result = gl::Texture::create( temp );
			result->update( data.get(), GL_RGB, dataType, 0, temp2.getWidth(), temp2.getHeight() );
			result->setTopDown( true );

			return result;
		}
	);
}

void TextureUploadApp::setup()
{
	mImg = loadImage( loadAsset( "fish.jpg" ) );
	mImgAlpha = loadImage( loadAsset( "fish_alpha.png" ) );
	mImg2 = loadImage( loadAsset( "fish2.jpg" ) );
	mImg2Alpha = loadImage( loadAsset( "fish2_alpha.png" ) );

	// 8bit unsigned void*
	{
		setupVoidStarConstructor<uint8_t>( 255 );
	}
	// 16bit signed void*
	{
		setupVoidStarConstructor<int16_t>( 32767 );
	}
	// 32bit signed void*
	{
		setupVoidStarConstructor<int32_t>( 2147483647 );
	}
	// 32bit unsigned void*
	{
		setupVoidStarConstructor<uint32_t>( 4294967295 );
	}

	// 8 bit
	{
		setupTexConstructor<uint8_t>();
		setupTexUpdate<uint8_t>();
	}

	// 16 bit
	{
		setupTexConstructor<uint16_t>();
		setupTexUpdate<uint16_t>();
	}

	// 32 bit
	{
		setupTexConstructor<uint8_t>();
		setupTexUpdate<uint8_t>();
	}

	mCurFnIdx = 0;
	mCurTex = mTexGenFns[mCurFnIdx]();
}

void TextureUploadApp::mouseDown( MouseEvent event )
{
	mCurFnIdx = ( mCurFnIdx + 1 ) % mTexGenFns.size();
	mCurTex = mTexGenFns[mCurFnIdx]();
	console() << *mCurTex << std::endl;
}

void TextureUploadApp::draw()
{
	gl::clear( Color( 0.5f, 0.5f, 0.5f ) );
	gl::enableAlphaBlending();
	gl::draw( mCurTex );
}

CINDER_APP( TextureUploadApp, RendererGl, TextureUploadApp::prepareSettings )
<commit_msg>Minor updates to test/TextureUpload<commit_after>#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"
#include "cinder/ip/Fill.h"

using namespace ci;
using namespace ci::app;
using namespace std;

class TextureUploadApp : public App {
  public:
	static void prepareSettings( Settings *settings ) { settings->setMultiTouchEnabled( false ); }
	void setup();
	template<typename T>
	void setupTexConstructor();
	template<typename T>
	void setupTexUpdate();

	template<typename T>
	void setupVoidStar( int64_t maxV );

	void mouseDown( MouseEvent event ) override;
	void draw() override;

	gl::TextureRef		mCurTex;
	ImageSourceRef		mImg, mImg2, mImgAlpha, mImg2Alpha;

	template<typename T>
	gl::TextureRef genTexConstructor( bool color, bool alpha );
	template<typename T>
	gl::TextureRef genTexUpdate( bool color, bool alpha );

	size_t										mCurFnIdx;
	vector<function<gl::TextureRef(void)>>		mTexGenFns;
};

template<typename T>
gl::TextureRef TextureUploadApp::genTexConstructor( bool color, bool alpha )
{
	if( color && alpha ) {
		SurfaceT<T> s( mImgAlpha );
		return gl::Texture::create( s );
	}
	else if( color ) {
		SurfaceT<T> s( mImg );
		return gl::Texture::create( s );
	}
	else { // grayscale
		ChannelT<T> s( mImg );
		return gl::Texture::create( s );
	}
}

template<typename T>
gl::TextureRef TextureUploadApp::genTexUpdate( bool color, bool alpha )
{
	if( color && alpha ) {
		SurfaceT<T> s0( mImgAlpha );
		gl::TextureRef result = gl::Texture::create( s0 );
		result->update( SurfaceT<T>( mImg2Alpha ) );
		return result;
	}
	else if( color ) {
		SurfaceT<T> s0( mImg );
		gl::TextureRef result = gl::Texture::create( s0 );
		result->update( SurfaceT<T>( mImg2 ) );
		return result;
	}
	else { // grayscale
		ChannelT<T> s0( mImg );
		gl::TextureRef result = gl::Texture::create( s0 );
		result->update( ChannelT<T>( mImg2 ) );
		return result;
	}
}

template<typename T>
void TextureUploadApp::setupTexConstructor()
{
	mTexGenFns.push_back( [=](void)->gl::TextureRef {
			app::console() << "Constructor Surface RGB " << sizeof(T) * 8 << "-bit" << std::endl;
			return genTexConstructor<T>( true, false );
		}
	);

	mTexGenFns.push_back( [=](void)->gl::TextureRef {
			app::console() << "Constructor Surface RGBA " << sizeof(T) * 8 << "-bit" << std::endl;
			return genTexConstructor<T>( true, true );
		}
	);

	mTexGenFns.push_back( [=](void)->gl::TextureRef {
			app::console() << "Constructor Channel " << sizeof(T) * 8 << "-bit" << std::endl;
			return genTexConstructor<T>( false, false );
		}
	);
}

template<typename T>
void TextureUploadApp::setupTexUpdate()
{
	mTexGenFns.push_back( [=](void)->gl::TextureRef {
			app::console() << "Update Surface RGB " << sizeof(T) * 8 << "-bit" << std::endl;
			return genTexUpdate<T>( true, false );
		}
	);

	mTexGenFns.push_back( [=](void)->gl::TextureRef {
			app::console() << "Update Surface RGBA " << sizeof(T) * 8 << "-bit" << std::endl;
			return genTexUpdate<T>( true, true );
		}
	);

	mTexGenFns.push_back( [=](void)->gl::TextureRef {
			app::console() << "Update Channel " << sizeof(T) * 8 << "-bit" << std::endl;
			return genTexUpdate<T>( false, false );
		}
	);

	mTexGenFns.push_back( [=](void)->gl::TextureRef {
			app::console() << "Update Subregion RGB " << sizeof(T) * 8 << "-bit" << std::endl;
			SurfaceT<T> srcImg( mImg );
			SurfaceT<T> square( 100, 100, false );
			gl::TextureRef result = gl::Texture::create( mImg2 );
			square.copyFrom( srcImg, Area( 28, 128, 28 + 100, 128 + 100 ), ivec2( -28, -128 ) );
			for( int y = 0; y < result->getHeight() / square.getHeight(); y += 2 ) {
				for( int x = y%2; x < result->getWidth() / square.getWidth(); x += 2 ) {
					result->update( square, 0, ivec2( x * square.getWidth(), y * square.getHeight() ) );
				}
			}
			return result;
		}
	);

	mTexGenFns.push_back( [=](void)->gl::TextureRef {
			app::console() << "Update Subregion Channel " << sizeof(T) * 8 << "-bit" << std::endl;
			ChannelT<T> srcImg( mImg );
			ChannelT<T> square( 100, 100 );
			gl::TextureRef result = gl::Texture::create( ChannelT<T>( mImg2 ) );
			square.copyFrom( srcImg, Area( 28, 128, 28 + 100, 128 + 100 ), ivec2( -28, -128 ) );
			for( int y = 0; y < result->getHeight() / square.getHeight(); y += 2 ) {
				for( int x = y%2; x < result->getWidth() / square.getWidth(); x += 2 ) {
					result->update( square, 0, ivec2( x * square.getWidth(), y * square.getHeight() ) );
				}
			}
			return result;
		}
	);
}

// This is for the constructor variant that accepts a void* to data, rather than a Surface/Channel
template<typename T>
void TextureUploadApp::setupVoidStar( int64_t maxV )
{
	GLenum dataType;
	if( std::is_same<T,uint8_t>::value )
		dataType = GL_UNSIGNED_BYTE;
	else if( std::is_same<T,int16_t>::value )
		dataType = GL_SHORT;
	else if( std::is_same<T,int32_t>::value )
		dataType = GL_INT;
	else if( std::is_same<T,uint32_t>::value )
		dataType = GL_UNSIGNED_INT;
	else
		throw;

	mTexGenFns.push_back( [=](void)->gl::TextureRef {
			app::console() << "void* Constructor: " << typeid(T).name() << sizeof(T) * 8 << "-bit" << std::endl;
			Surface8u temp( mImg );
			std::unique_ptr<T[]> data( new T[mImg->getWidth() * mImg->getHeight() * 3] );

			for( int y = 0; y < temp.getHeight(); ++y ) {
				for( int x = 0; x < temp.getWidth(); ++x ) {
					ColorA8u color = temp.getPixel( ivec2( x, y ) );
					data[(y*temp.getWidth()+x)*3 + 0] = color.r / 255.0f * maxV;
					data[(y*temp.getWidth()+x)*3 + 1] = color.g / 255.0f * maxV;
					data[(y*temp.getWidth()+x)*3 + 2] = color.b / 255.0f * maxV;
				}
			}
			gl::TextureRef result = gl::Texture::create( data.get(), GL_RGB, temp.getWidth(), temp.getHeight(),
											gl::Texture2d::Format().dataType( dataType ).internalFormat( GL_RGB ) );
			result->setTopDown( true );

			return result;
		}
	);

	mTexGenFns.push_back( [=](void)->gl::TextureRef {
			app::console() << "void* update: " << typeid(T).name() << sizeof(T) * 8 << "-bit" << std::endl;
			Surface8u temp( mImg );
			Surface8u temp2( mImg2 );
			std::unique_ptr<T[]> data( new T[mImg2->getWidth() * mImg2->getHeight() * 3] );

			for( int y = 0; y < temp2.getHeight(); ++y ) {
				for( int x = 0; x < temp2.getWidth(); ++x ) {
					ColorA8u color = temp2.getPixel( ivec2( x, y ) );
					data[(y*temp2.getWidth()+x)*3 + 0] = color.r / 255.0f * maxV;
					data[(y*temp2.getWidth()+x)*3 + 1] = color.g / 255.0f * maxV;
					data[(y*temp2.getWidth()+x)*3 + 2] = color.b / 255.0f * maxV;
				}
			}

			gl::TextureRef result = gl::Texture::create( temp );
			result->update( data.get(), GL_RGB, dataType, 0, temp2.getWidth(), temp2.getHeight() );
			result->setTopDown( true );

			return result;
		}
	);
}

void TextureUploadApp::setup()
{
	mImg = loadImage( loadAsset( "fish.jpg" ) );
	mImgAlpha = loadImage( loadAsset( "fish_alpha.png" ) );
	mImg2 = loadImage( loadAsset( "fish2.jpg" ) );
	mImg2Alpha = loadImage( loadAsset( "fish2_alpha.png" ) );

	// 8bit unsigned void*
	{
		setupVoidStar<uint8_t>( 255 );
	}
	// 16bit signed void*
	{
		setupVoidStar<int16_t>( 32767 );
	}
	// 32bit signed void*
	{
		setupVoidStar<int32_t>( 2147483647 );
	}
	// 32bit unsigned void*
	{
		setupVoidStar<uint32_t>( 4294967295 );
	}

	// 8 bit
	{
		setupTexConstructor<uint8_t>();
		setupTexUpdate<uint8_t>();
	}

	// 16 bit
	{
		setupTexConstructor<uint16_t>();
		setupTexUpdate<uint16_t>();
	}

	// 32 bit
	{
		setupTexConstructor<uint8_t>();
		setupTexUpdate<uint8_t>();
	}

	mCurFnIdx = 0;
	mCurTex = mTexGenFns[mCurFnIdx]();
}

void TextureUploadApp::mouseDown( MouseEvent event )
{
	mCurFnIdx = ( mCurFnIdx + 1 ) % mTexGenFns.size();
	mCurTex = mTexGenFns[mCurFnIdx]();
	console() << *mCurTex << std::endl;
}

void TextureUploadApp::draw()
{
	gl::clear( Color( 0.5f, 0.5f, 0.5f ) );
	gl::enableAlphaBlending();
	gl::draw( mCurTex );
}

CINDER_APP( TextureUploadApp, RendererGl, TextureUploadApp::prepareSettings )
<|endoftext|>


<commit_before>// The libMesh Finite Element Library.
// Copyright (C) 2002-2021 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

//
FEMSystem Example 2

// \author Robert Weidlich
// \date 2012

#include "libmesh/equation_systems.h"
#include "libmesh/getpot.h"
#include "libmesh/libmesh.h"
#include "libmesh/libmesh_logging.h"
#include "libmesh/mesh.h"
#include "libmesh/mesh_generation.h"
#include "libmesh/numeric_vector.h"
#include "libmesh/string_to_enum.h"
#include "libmesh/time_solver.h"
#include "libmesh/transient_system.h"
#include "libmesh/vtk_io.h"
#include "libmesh/auto_ptr.h" // libmesh_make_unique
#include "libmesh/enum_solver_package.h"

#include <cstdio>
#include <ctime>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <unistd.h>

using namespace libMesh;

#include "solid_system.h"

void setup(EquationSystems & systems,
           Mesh & mesh,
           GetPot & args)
{
  const unsigned int dim = mesh.mesh_dimension();
  // We currently invert tensors with the assumption that they're 3x3
  libmesh_assert (dim == 3);

  // Generating Mesh
  ElemType eltype = Utility::string_to_enum<ElemType>(args("mesh/generation/element_type", "hex8"));
  int nx = args("mesh/generation/num_elem", 4, 0);
  int ny = args("mesh/generation/num_elem", 4, 1);
  int nz = dim > 2 ? args("mesh/generation/num_elem", 4, 2) : 0;
  double origx = args("mesh/generation/origin", -1.0, 0);
  double origy = args("mesh/generation/origin", -1.0, 1);
  double origz = args("mesh/generation/origin", 0.0, 2);
  double sizex = args("mesh/generation/size", 2.0, 0);
  double sizey = args("mesh/generation/size", 2.0, 1);
  double sizez = args("mesh/generation/size", 2.0, 2);
  MeshTools::Generation::build_cube(mesh, nx, ny, nz,
                                    origx, origx+sizex, origy, origy+sizey, origz, origz+sizez, eltype);

  // Creating Systems
  SolidSystem & imms = systems.add_system<SolidSystem> ("solid");
  imms.args = args;

  // Build up auxiliary system
  ExplicitSystem & aux_sys = systems.add_system<TransientExplicitSystem>("auxiliary");

  // Initialize the system
  systems.parameters.set<unsigned int>("phase") = 0;
  systems.init();

  imms.save_initial_mesh();

  // Fill global solution vector from local ones
  aux_sys.current_local_solution->close();
  *aux_sys.solution = *aux_sys.current_local_solution;
  aux_sys.solution->close();
}

void run_timestepping(EquationSystems & systems, GetPot & args)
{
  TransientExplicitSystem & aux_system = systems.get_system<TransientExplicitSystem>("auxiliary");

  SolidSystem & solid_system = systems.get_system<SolidSystem>("solid");

  std::unique_ptr<VTKIO> io = libmesh_make_unique<VTKIO>(systems.get_mesh());

  Real duration = args("duration", 1.0);

  for (unsigned int t_step = 0; t_step < duration/solid_system.deltat; t_step++)
    {
      // Progress in current phase [0..1]
      Real progress = t_step * solid_system.deltat / duration;
      systems.parameters.set<Real>("progress") = progress;
      systems.parameters.set<unsigned int>("step") = t_step;

      // Update message

      out << "===== Time Step " << std::setw(4) << t_step;
      out << " (" << std::fixed << std::setprecision(2) << std::setw(6) << (progress*100.) << "%)";
      out << ", time = " << std::setw(7) << solid_system.time;
      out << " =====" << std::endl;

      // Advance timestep in auxiliary system
      aux_system.current_local_solution->close();
      aux_system.old_local_solution->close();
      *aux_system.older_local_solution = *aux_system.old_local_solution;
      *aux_system.old_local_solution = *aux_system.current_local_solution;

      out << "Solving Solid" << std::endl;
      solid_system.solve();
      aux_system.current_local_solution->close();
      *aux_system.solution = *aux_system.current_local_solution;
      aux_system.solution->close();

      // Carry out the adaptive mesh refinement/coarsening
      out << "Doing a reinit of the equation systems" << std::endl;
      systems.reinit();

      if (t_step % args("output/frequency", 1) == 0)
        {
          std::stringstream file_name;
          file_name << args("results_directory", "./")
                    << "fem_"
                    << std::setw(6)
                    << std::setfill('0')
                    << t_step
                    << ".pvtu";

          io->write_equation_systems(file_name.str(), systems);
        }
      // Advance to the next timestep in a transient problem
      out << "Advancing to next step" << std::endl;
      solid_system.time_solver->advance_timestep();
    }
}

int main(int argc, char ** argv)
{
  // Initialize libMesh and any dependent libraries
  LibMeshInit init(argc, argv);

  // This example requires a linear solver package.
  libmesh_example_requires(libMesh::default_solver_package() != INVALID_SOLVER_PACKAGE,
                           "--enable-petsc, --enable-trilinos, or --enable-eigen");

  // Skip this example if we do not meet certain requirements
#ifndef LIBMESH_HAVE_VTK
  libmesh_example_requires(false, "--enable-vtk");
#endif

  // Trilinos gives us an inverted element on this one...
  libmesh_example_requires(libMesh::default_solver_package() != TRILINOS_SOLVERS, "--enable-petsc");

  // Threaded assembly doesn't currently work with the moving mesh
  // code.
  // We'll skip this example for now.
  if (libMesh::n_threads() > 1)
    {
      libMesh::out << "We skip fem_system_ex2 when using threads.\n"
                   << std::endl;
      return 0;
    }

  // read simulation parameters from file
  GetPot args = GetPot("solid.in");

  // Create System and Mesh
  int dim = args("mesh/generation/dimension", 3);
  libmesh_example_requires(dim <= LIBMESH_DIM, "3D support");

  // Create a mesh distributed across the default MPI communicator.
  Mesh mesh(init.comm(), cast_int<unsigned char>(dim));

  EquationSystems systems(mesh);

  // Create and set systems up
  setup(systems, mesh, args);

  // run the systems
  run_timestepping(systems, args);

  out << "Finished calculations" << std::endl;
  return 0;
}
<commit_msg>mesh.print_info() in fem_system_ex2<commit_after>// The libMesh Finite Element Library.
// Copyright (C) 2002-2021 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

//
FEMSystem Example 2

// \author Robert Weidlich
// \date 2012

#include "libmesh/equation_systems.h"
#include "libmesh/getpot.h"
#include "libmesh/libmesh.h"
#include "libmesh/libmesh_logging.h"
#include "libmesh/mesh.h"
#include "libmesh/mesh_generation.h"
#include "libmesh/numeric_vector.h"
#include "libmesh/string_to_enum.h"
#include "libmesh/time_solver.h"
#include "libmesh/transient_system.h"
#include "libmesh/vtk_io.h"
#include "libmesh/auto_ptr.h" // libmesh_make_unique
#include "libmesh/enum_solver_package.h"

#include <cstdio>
#include <ctime>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <unistd.h>

using namespace libMesh;

#include "solid_system.h"

void setup(EquationSystems & systems,
           Mesh & mesh,
           GetPot & args)
{
  const unsigned int dim = mesh.mesh_dimension();
  // We currently invert tensors with the assumption that they're 3x3
  libmesh_assert (dim == 3);

  // Generating Mesh
  ElemType eltype = Utility::string_to_enum<ElemType>(args("mesh/generation/element_type", "hex8"));
  int nx = args("mesh/generation/num_elem", 4, 0);
  int ny = args("mesh/generation/num_elem", 4, 1);
  int nz = dim > 2 ? args("mesh/generation/num_elem", 4, 2) : 0;
  double origx = args("mesh/generation/origin", -1.0, 0);
  double origy = args("mesh/generation/origin", -1.0, 1);
  double origz = args("mesh/generation/origin", 0.0, 2);
  double sizex = args("mesh/generation/size", 2.0, 0);
  double sizey = args("mesh/generation/size", 2.0, 1);
  double sizez = args("mesh/generation/size", 2.0, 2);
  MeshTools::Generation::build_cube(mesh, nx, ny, nz,
                                    origx, origx+sizex, origy, origy+sizey, origz, origz+sizez, eltype);
  mesh.print_info();

  // Creating Systems
  SolidSystem & imms = systems.add_system<SolidSystem> ("solid");
  imms.args = args;

  // Build up auxiliary system
  ExplicitSystem & aux_sys = systems.add_system<TransientExplicitSystem>("auxiliary");

  // Initialize the system
  systems.parameters.set<unsigned int>("phase") = 0;
  systems.init();

  imms.save_initial_mesh();

  // Fill global solution vector from local ones
  aux_sys.current_local_solution->close();
  *aux_sys.solution = *aux_sys.current_local_solution;
  aux_sys.solution->close();
}

void run_timestepping(EquationSystems & systems, GetPot & args)
{
  TransientExplicitSystem & aux_system = systems.get_system<TransientExplicitSystem>("auxiliary");

  SolidSystem & solid_system = systems.get_system<SolidSystem>("solid");

  std::unique_ptr<VTKIO> io = libmesh_make_unique<VTKIO>(systems.get_mesh());

  Real duration = args("duration", 1.0);

  for (unsigned int t_step = 0; t_step < duration/solid_system.deltat; t_step++)
    {
      // Progress in current phase [0..1]
      Real progress = t_step * solid_system.deltat / duration;
      systems.parameters.set<Real>("progress") = progress;
      systems.parameters.set<unsigned int>("step") = t_step;

      // Update message

      out << "===== Time Step " << std::setw(4) << t_step;
      out << " (" << std::fixed << std::setprecision(2) << std::setw(6) << (progress*100.) << "%)";
      out << ", time = " << std::setw(7) << solid_system.time;
      out << " =====" << std::endl;

      // Advance timestep in auxiliary system
      aux_system.current_local_solution->close();
      aux_system.old_local_solution->close();
      *aux_system.older_local_solution = *aux_system.old_local_solution;
      *aux_system.old_local_solution = *aux_system.current_local_solution;

      out << "Solving Solid" << std::endl;
      solid_system.solve();
      aux_system.current_local_solution->close();
      *aux_system.solution = *aux_system.current_local_solution;
      aux_system.solution->close();

      // Carry out the adaptive mesh refinement/coarsening
      out << "Doing a reinit of the equation systems" << std::endl;
      systems.reinit();

      if (t_step % args("output/frequency", 1) == 0)
        {
          std::stringstream file_name;
          file_name << args("results_directory", "./")
                    << "fem_"
                    << std::setw(6)
                    << std::setfill('0')
                    << t_step
                    << ".pvtu";

          io->write_equation_systems(file_name.str(), systems);
        }
      // Advance to the next timestep in a transient problem
      out << "Advancing to next step" << std::endl;
      solid_system.time_solver->advance_timestep();
    }
}

int main(int argc, char ** argv)
{
  // Initialize libMesh and any dependent libraries
  LibMeshInit init(argc, argv);

  // This example requires a linear solver package.
  libmesh_example_requires(libMesh::default_solver_package() != INVALID_SOLVER_PACKAGE,
                           "--enable-petsc, --enable-trilinos, or --enable-eigen");

  // Skip this example if we do not meet certain requirements
#ifndef LIBMESH_HAVE_VTK
  libmesh_example_requires(false, "--enable-vtk");
#endif

  // Trilinos gives us an inverted element on this one...
  libmesh_example_requires(libMesh::default_solver_package() != TRILINOS_SOLVERS, "--enable-petsc");

  // Threaded assembly doesn't currently work with the moving mesh
  // code.
  // We'll skip this example for now.
  if (libMesh::n_threads() > 1)
    {
      libMesh::out << "We skip fem_system_ex2 when using threads.\n"
                   << std::endl;
      return 0;
    }

  // read simulation parameters from file
  GetPot args = GetPot("solid.in");

  // Create System and Mesh
  int dim = args("mesh/generation/dimension", 3);
  libmesh_example_requires(dim <= LIBMESH_DIM, "3D support");

  // Create a mesh distributed across the default MPI communicator.
  Mesh mesh(init.comm(), cast_int<unsigned char>(dim));

  EquationSystems systems(mesh);

  // Create and set systems up
  setup(systems, mesh, args);

  // run the systems
  run_timestepping(systems, args);

  out << "Finished calculations" << std::endl;
  return 0;
}
<|endoftext|>


<commit_before>
#include <iostream>
#include "ctc_beam_entry.h"
#include "ctc_beam_scorer.h"
#include "ctc_beam_search.h"
#include "ctc_decoder.h"
#include "util/status.h"
#include "TH.h"

namespace pytorch {
  extern "C"
  {
      int ctc_beam_decode(THFloatTensor *th_probs, THIntTensor *th_seq_len, THIntTensor *th_output,
                          THFloatTensor *th_scores, int top_paths, int beam_width, int merge_repeated)
      {
        const int64_t max_time = THFloatTensor_size(th_probs, 0);
        const int64_t batch_size = THFloatTensor_size(th_probs, 1);
        const int64_t num_classes = THFloatTensor_size(th_probs, 2);

        // TODO: DEBUG, Remove
        std::cout << "Max Timesteps: " << max_time << "\nBatch Size: " << batch_size << "\nNumber of Classes: " << num_classes << std::endl;
        // convert tensors to something the beam scorer can use
        // sequence length
        int* seq_len_ptr = THIntTensor_data(th_seq_len);
        ptrdiff_t seq_len_offset = THIntTensor_storageOffset(th_seq_len);
        Eigen::Map<const Eigen::ArrayXi> seq_len(seq_len_ptr + seq_len_offset, batch_size);
        std::cout << "STATUS: Converted sequence_length tensor" << std::endl;
        //std::cout << "DEBUG: seq_len=" << seq_len << std::endl;

        // input logits
        float* probs_ptr = THFloatTensor_data(th_probs);
        ptrdiff_t probs_offset = THFloatTensor_storageOffset(th_probs);
        const int64_t probs_stride_0 = THFloatTensor_stride(th_probs, 0);
        std::vector<Eigen::Map<const Eigen::MatrixXf>> inputs;
        for (int t=0; t < max_time; ++t) {
          inputs.emplace_back(probs_ptr + probs_offset + (t*probs_stride_0), batch_size, num_classes);
          //std::cout << inputs[t] << std::endl;
        }
        std::cout << "STATUS: Converted input logits tensor" << std::endl;
        // std::cout << "printing flattened input matrix..." << std::endl;
        // for (int t=0; t < max_time; ++t) {
        //   std::cout << t << ": " << th_probs_ptr[t] << std::endl;
        // }

        // prepare/initialize output variables
        // paths, batches, class
        std::vector<ctc::CTCDecoder::Output> outputs(top_paths);
        std::cout << "Output size: " << outputs.size() << std::endl;
        for (ctc::CTCDecoder::Output& output : outputs) {
          output.resize(batch_size);
        }
        std::cout << "STATUS: Output char vector created" << std::endl;

        float score[batch_size][top_paths] = {{0.0}};
        Eigen::Map<Eigen::MatrixXf> scores(&score[0][0], batch_size, beam_width);
        std::cout << "STATUS: Output score vector created" << std::endl;

        // initialize beam scorer (TODO: make this extensible)
        ctc::CTCBeamSearchDecoder<>::DefaultBeamScorer beam_scorer;

        // initialize beam search class
        ctc::CTCBeamSearchDecoder<> beam_search(num_classes, beam_width, &beam_scorer,
                                                batch_size, merge_repeated == 1);
        std::cout << "STATUS: beam decoder initialized" << std::endl;

        ctc::Status stat = beam_search.Decode(seq_len, inputs, &outputs, &scores);
        if (!stat.ok()) {
          std::cout << "ERROR: " << stat.error_message() << std::endl;
          return 0;
        }
        std::cout << "STATUS: decode executed" << std::endl;
        std::vector<float> log_probs;

        for (int p=0; p < top_paths; ++p) {
          int64_t max_decoded = 0;
          int64_t offset = 0;
          for (int b=0; b < batch_size; ++b) {
            auto& p_batch = outputs[p][b];
            //std::cout << b << " " << p << std::endl;
            int64_t num_decoded = p_batch.size();

            max_decoded = std::max(max_decoded, num_decoded);
            //std::cout << "Path " << p << ", batch " << b << ":";
            for (int64_t t=0; t < num_decoded; ++t) {
              // TODO: this could be more efficient (significant pointer arithmetic every time currently)
              THIntTensor_set3d(th_output, p, b, t, p_batch[t]);
              THFloatTensor_set2d(th_scores, p, b, scores(b, p));
              //std::cout << p_batch[t] << " ";
            }
            for (int64_t t = num_decoded; t < max_time; ++t) {
              THIntTensor_set3d(th_output, p, b, t, -1);
            }
            // std::cout << std::endl;
          }
        }

        return 1;
      }
  }
}
<commit_msg>Remove debug output<commit_after>
#include <iostream>
#include "ctc_beam_entry.h"
#include "ctc_beam_scorer.h"
#include "ctc_beam_search.h"
#include "ctc_decoder.h"
#include "util/status.h"
#include "TH.h"

namespace pytorch {
  extern "C"
  {
      int ctc_beam_decode(THFloatTensor *th_probs, THIntTensor *th_seq_len, THIntTensor *th_output,
                          THFloatTensor *th_scores, int top_paths, int beam_width, int merge_repeated)
      {
        const int64_t max_time = THFloatTensor_size(th_probs, 0);
        const int64_t batch_size = THFloatTensor_size(th_probs, 1);
        const int64_t num_classes = THFloatTensor_size(th_probs, 2);

        // convert tensors to something the beam scorer can use
        // sequence length
        int* seq_len_ptr = THIntTensor_data(th_seq_len);
        ptrdiff_t seq_len_offset = THIntTensor_storageOffset(th_seq_len);
        Eigen::Map<const Eigen::ArrayXi> seq_len(seq_len_ptr + seq_len_offset, batch_size);

        // input logits
        float* probs_ptr = THFloatTensor_data(th_probs);
        ptrdiff_t probs_offset = THFloatTensor_storageOffset(th_probs);
        const int64_t probs_stride_0 = THFloatTensor_stride(th_probs, 0);
        std::vector<Eigen::Map<const Eigen::MatrixXf>> inputs;
        for (int t=0; t < max_time; ++t) {
          inputs.emplace_back(probs_ptr + probs_offset + (t*probs_stride_0), batch_size, num_classes);
        }

        // prepare/initialize output variables
        // paths, batches, class
        std::vector<ctc::CTCDecoder::Output> outputs(top_paths);
        for (ctc::CTCDecoder::Output& output : outputs) {
          output.resize(batch_size);
        }

        float score[batch_size][top_paths] = {{0.0}};
        Eigen::Map<Eigen::MatrixXf> scores(&score[0][0], batch_size, beam_width);

        // initialize beam scorer (TODO: make this extensible)
        ctc::CTCBeamSearchDecoder<>::DefaultBeamScorer beam_scorer;

        // initialize beam search class
        ctc::CTCBeamSearchDecoder<> beam_search(num_classes, beam_width, &beam_scorer,
                                                batch_size, merge_repeated == 1);

        ctc::Status stat = beam_search.Decode(seq_len, inputs, &outputs, &scores);
        if (!stat.ok()) {
          return 0;
        }
        std::vector<float> log_probs;

        for (int p=0; p < top_paths; ++p) {
          int64_t max_decoded = 0;
          int64_t offset = 0;
          for (int b=0; b < batch_size; ++b) {
            auto& p_batch = outputs[p][b];
            int64_t num_decoded = p_batch.size();

            max_decoded = std::max(max_decoded, num_decoded);
            for (int64_t t=0; t < num_decoded; ++t) {
              // TODO: this could be more efficient (significant pointer arithmetic every time currently)
              THIntTensor_set3d(th_output, p, b, t, p_batch[t]);
              THFloatTensor_set2d(th_scores, p, b, scores(b, p));
            }
            for (int64_t t = num_decoded; t < max_time; ++t) {
              THIntTensor_set3d(th_output, p, b, t, -1);
            }
          }
        }
        return 1;
      }
  }
}
<|endoftext|>


<commit_before>// RUN: %clang_cl_asan -O0 %p/dll_host.cc -Fe%t
// RUN: %clang_cl_asan -LD -O0 %s -Fe%t.dll
// RUN: not %run %t %t.dll 2>&1 | FileCheck %s

#include <string.h>

extern "C" __declspec(dllexport)
int test_function() {
  char buff[6] = "Hello";

  memchr(buff, 'z', 7);
// CHECK: AddressSanitizer: stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]]
// CHECK: READ of size 7 at [[ADDR]] thread T0
// CHECK-NEXT:  __asan_wrap_memchr
// CHECK-NEXT:  memchr
// CHECK-NEXT:  test_function {{.*}}dll_intercept_memchr.cc:[[@LINE-5]]
// CHECK: Address [[ADDR]] is located in stack of thread T0 at offset {{.*}} in frame
// CHECK-NEXT:  test_function {{.*}}dll_intercept_memchr.cc
// CHECK: 'buff' <== Memory access at offset {{.*}} overflows this variable
  return 0;
}
<commit_msg>[compiler-rt][asan] Disable a broken test on windows 64-bits<commit_after>// RUN: %clang_cl_asan -O0 %p/dll_host.cc -Fe%t
// RUN: %clang_cl_asan -LD -O0 %s -Fe%t.dll
// RUN: not %run %t %t.dll 2>&1 | FileCheck %s

// On windows 64-bit, the memchr function is written in assembly and is not
// hookable with the interception library. There is not enough padding before
// the function and there is a short jump on the second instruction which
// doesn't not allow enough space to encode a 64-bit indirect jump.
// UNSUPPORTED: x86_64-windows

#include <string.h>

extern "C" __declspec(dllexport)
int test_function() {
  char buff[6] = "Hello";

  memchr(buff, 'z', 7);
// CHECK: AddressSanitizer: stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]]
// CHECK: READ of size 7 at [[ADDR]] thread T0
// CHECK-NEXT:  __asan_wrap_memchr
// CHECK-NEXT:  memchr
// CHECK-NEXT:  test_function {{.*}}dll_intercept_memchr.cc:[[@LINE-5]]
// CHECK: Address [[ADDR]] is located in stack of thread T0 at offset {{.*}} in frame
// CHECK-NEXT:  test_function {{.*}}dll_intercept_memchr.cc
// CHECK: 'buff' <== Memory access at offset {{.*}} overflows this variable
  return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <algorithm>

#include "webkit/appcache/view_appcache_internals_job.h"

#include "base/logging.h"
#include "base/format_macros.h"
#include "base/utf_string_conversions.h"
#include "base/i18n/time_formatting.h"
#include "base/string_util.h"
#include "net/base/escape.h"
#include "net/url_request/url_request.h"
#include "webkit/appcache/appcache_policy.h"
#include "webkit/appcache/appcache_service.h"

namespace {

const char kErrorMessage[] = "Error in retrieving Application Caches.";
const char kEmptyAppCachesMessage[] = "No available Application Caches.";
const char kRemoveAppCache[] = "Remove this AppCache";
const char kManifest[] = "Manifest: ";
const char kSize[] = "Size: ";
const char kCreationTime[] = "Creation Time: ";
const char kLastAccessTime[] = "Last Access Time: ";
const char kLastUpdateTime[] = "Last Update Time: ";
const char kFormattedDisabledAppCacheMsg[] =
    ""
    "This Application Cache is disabled by policy.
";

void StartHTML(std::string* out) {
  DCHECK(out);
  out->append(
      "<!DOCTYPE HTML>"
      "<title>AppCache Internals</title>"
      ""
      "\n"
      ""
      "<form action='' method=GET id=cmdsender>"
      "<input type='hidden' id=cmd name='remove'>"
      "</form>");
}

void EndHTML(std::string* out) {
  DCHECK(out);
  out->append("");
}

// Appends an input button to |data| with text |title| that sends the command
// string |command| back to the browser, and then refreshes the page.
void DrawCommandButton(const std::string& title,
                       const std::string& command,
                       std::string* data) {
  base::StringAppendF(data, "<input type=\"button\" value=\"%s\" "
                      "onclick=\"RemoveCommand('%s')\" />",
                      title.c_str(),
                      command.c_str());
}

void AddLiTag(const std::string& element_title,
              const std::string& element_data, std::string* out) {
  DCHECK(out);
  out->append("
");
  out->append(element_title);
  out->append(element_data);
  out->append("
");
}

void WrapInHREF(const std::string& in, std::string* out) {
  out->append("append(in);
  out->append("'>");
  out->append(in);
  out->append("
");
}

void AddHTMLFromAppCacheToOutput(
    const appcache::AppCacheService& appcache_service,
    const appcache::AppCacheInfoVector& appcaches, std::string* out) {
  for (std::vector<appcache::AppCacheInfo>::const_iterator info =
           appcaches.begin();
       info != appcaches.end(); ++info) {
    out->append("
");
    std::string anchored_manifest;
    WrapInHREF(info->manifest_url.spec(), &anchored_manifest);
    out->append(kManifest);
    out->append(anchored_manifest);
    if (!appcache_service.appcache_policy()->CanLoadAppCache(
            info->manifest_url)) {
      out->append(kFormattedDisabledAppCacheMsg);
    }
    out->append("
");
    DrawCommandButton(kRemoveAppCache, info->manifest_url.spec(), out);
    out->append("
");

    AddLiTag(kSize,
             UTF16ToUTF8(FormatBytes(
                 info->size, GetByteDisplayUnits(info->size), true)),
             out);
    AddLiTag(kCreationTime,
             UTF16ToUTF8(TimeFormatFriendlyDateAndTime(info->creation_time)),
             out);
    AddLiTag(kLastAccessTime,
             UTF16ToUTF8(TimeFormatFriendlyDateAndTime(info->last_access_time)),
             out);
    AddLiTag(kLastUpdateTime,
             UTF16ToUTF8(TimeFormatFriendlyDateAndTime(info->last_update_time)),
             out);

    out->append("

");
  }
}

std::string GetAppCacheManifestToRemove(const std::string& query) {
  if (!StartsWithASCII(query, "remove=", true)) {
    // Not a recognized format.
    return std::string();
  }
  std::string manifest_str = query.substr(strlen("remove="));
  return UnescapeURLComponent(
      manifest_str, UnescapeRule::NORMAL | UnescapeRule::URL_SPECIAL_CHARS);
}

struct ManifestURLComparator {
 public:
  bool operator() (
      const appcache::AppCacheInfo& lhs,
      const appcache::AppCacheInfo& rhs) const {
    return (lhs.manifest_url.spec() < rhs.manifest_url.spec());
  }
} manifest_url_comparator;

}  // namespace

namespace appcache {

ViewAppCacheInternalsJob::ViewAppCacheInternalsJob(
    net::URLRequest* request,
    AppCacheService* service)
    : net::URLRequestSimpleJob(request),
      appcache_service_(service) {
}

ViewAppCacheInternalsJob::~ViewAppCacheInternalsJob() {
  // Cancel callback if job is destroyed before callback is called.
  if (appcache_done_callback_)
    appcache_done_callback_.release()->Cancel();
}

void ViewAppCacheInternalsJob::GetAppCacheInfoAsync() {
  info_collection_ = new AppCacheInfoCollection;
  appcache_done_callback_ =
      new net::CancelableCompletionCallback<ViewAppCacheInternalsJob>(
          this, &ViewAppCacheInternalsJob::AppCacheDone);
  appcache_service_->GetAllAppCacheInfo(
      info_collection_, appcache_done_callback_);
}

void ViewAppCacheInternalsJob::RemoveAppCacheInfoAsync(
    const std::string& manifest_url_spec) {
  appcache_done_callback_ =
      new net::CancelableCompletionCallback<ViewAppCacheInternalsJob>(
          this, &ViewAppCacheInternalsJob::AppCacheDone);

  GURL manifest(manifest_url_spec);
  appcache_service_->DeleteAppCacheGroup(
      manifest, appcache_done_callback_);
}

void ViewAppCacheInternalsJob::Start() {
  if (!request_)
    return;

  // Handle any remove appcache request, then redirect back to
  // the same URL stripped of query parameters. The redirect happens as part
  // of IsRedirectResponse().
  if (request_->url().has_query()) {
    std::string remove_appcache_manifest(
        GetAppCacheManifestToRemove(request_->url().query()));

    // Empty manifests are dealt with by the deleter.
    RemoveAppCacheInfoAsync(remove_appcache_manifest);
  } else {
    GetAppCacheInfoAsync();
  }
}

bool ViewAppCacheInternalsJob::IsRedirectResponse(
    GURL* location, int* http_status_code) {
  if (request_->url().has_query()) {
    // Strip the query parameters.
    GURL::Replacements replacements;
    replacements.ClearQuery();
    *location = request_->url().ReplaceComponents(replacements);
    *http_status_code = 307;
    return true;
  }
  return false;
}

void ViewAppCacheInternalsJob::GenerateHTMLAppCacheInfo(
    std::string* out) const {
  typedef std::map<GURL, AppCacheInfoVector> InfoByOrigin;
  AppCacheInfoVector appcaches;
  for (InfoByOrigin::const_iterator origin =
           info_collection_->infos_by_origin.begin();
       origin != info_collection_->infos_by_origin.end(); ++origin) {
    for (AppCacheInfoVector::const_iterator info =
             origin->second.begin(); info != origin->second.end(); ++info)
      appcaches.push_back(*info);
  }

  std::sort(appcaches.begin(), appcaches.end(), manifest_url_comparator);

  AddHTMLFromAppCacheToOutput(*appcache_service_, appcaches, out);
}

void ViewAppCacheInternalsJob::AppCacheDone(int rv) {
  appcache_done_callback_ = NULL;
  if (rv != net::OK)
    info_collection_ = NULL;
  StartAsync();
}

bool ViewAppCacheInternalsJob::GetData(std::string* mime_type,
                                       std::string* charset,
                                       std::string* data) const {
  mime_type->assign("text/html");
  charset->assign("UTF-8");

  data->clear();
  StartHTML(data);
  if (!info_collection_.get())
    data->append(kErrorMessage);
  else if (info_collection_->infos_by_origin.empty())
    data->append(kEmptyAppCachesMessage);
  else
    GenerateHTMLAppCacheInfo(data);
  EndHTML(data);
  return true;
}

}  // namespace appcache
<commit_msg>Base64 encode form param values in about:appcache-internals <commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <algorithm>

#include "webkit/appcache/view_appcache_internals_job.h"

#include "base/base64.h"
#include "base/logging.h"
#include "base/format_macros.h"
#include "base/utf_string_conversions.h"
#include "base/i18n/time_formatting.h"
#include "base/string_util.h"
#include "net/base/escape.h"
#include "net/url_request/url_request.h"
#include "webkit/appcache/appcache_policy.h"
#include "webkit/appcache/appcache_service.h"

namespace {

const char kErrorMessage[] = "Error in retrieving Application Caches.";
const char kEmptyAppCachesMessage[] = "No available Application Caches.";
const char kRemoveAppCache[] = "Remove this AppCache";
const char kManifest[] = "Manifest: ";
const char kSize[] = "Size: ";
const char kCreationTime[] = "Creation Time: ";
const char kLastAccessTime[] = "Last Access Time: ";
const char kLastUpdateTime[] = "Last Update Time: ";
const char kFormattedDisabledAppCacheMsg[] =
    ""
    "This Application Cache is disabled by policy.
";

void StartHTML(std::string* out) {
  DCHECK(out);
  out->append(
      "<!DOCTYPE HTML>"
      "<title>AppCache Internals</title>"
      ""
      "\n"
      ""
      "<form action='' method=GET id=cmdsender>"
      "<input type='hidden' id=cmd name='remove'>"
      "</form>");
}

void EndHTML(std::string* out) {
  DCHECK(out);
  out->append("");
}

// Appends an input button to |data| with text |title| that sends the command
// string |command| back to the browser, and then refreshes the page.
void DrawCommandButton(const std::string& title,
                       const std::string& command,
                       std::string* data) {
  base::StringAppendF(data, "<input type=\"button\" value=\"%s\" "
                      "onclick=\"RemoveCommand('%s')\" />",
                      title.c_str(),
                      command.c_str());
}

void AddLiTag(const std::string& element_title,
              const std::string& element_data, std::string* out) {
  DCHECK(out);
  out->append("
");
  out->append(element_title);
  out->append(element_data);
  out->append("
");
}

void WrapInHREF(const std::string& in, std::string* out) {
  out->append("append(in);
  out->append(">");
  out->append(in);
  out->append("
");
}

void AddHTMLFromAppCacheToOutput(
    const appcache::AppCacheService& appcache_service,
    const appcache::AppCacheInfoVector& appcaches, std::string* out) {
  for (std::vector<appcache::AppCacheInfo>::const_iterator info =
           appcaches.begin();
       info != appcaches.end(); ++info) {
    std::string manifest_url_base64;
    base::Base64Encode(info->manifest_url.spec(), &manifest_url_base64);

    out->append("
");
    std::string anchored_manifest;
    WrapInHREF(info->manifest_url.spec(), &anchored_manifest);
    out->append(kManifest);
    out->append(anchored_manifest);
    if (!appcache_service.appcache_policy()->CanLoadAppCache(
            info->manifest_url)) {
      out->append(kFormattedDisabledAppCacheMsg);
    }
    out->append("
");
    DrawCommandButton(kRemoveAppCache, manifest_url_base64, out);
    out->append("
");

    AddLiTag(kSize,
             UTF16ToUTF8(FormatBytes(
                 info->size, GetByteDisplayUnits(info->size), true)),
             out);
    AddLiTag(kCreationTime,
             UTF16ToUTF8(TimeFormatFriendlyDateAndTime(info->creation_time)),
             out);
    AddLiTag(kLastAccessTime,
             UTF16ToUTF8(TimeFormatFriendlyDateAndTime(info->last_access_time)),
             out);
    AddLiTag(kLastUpdateTime,
             UTF16ToUTF8(TimeFormatFriendlyDateAndTime(info->last_update_time)),
             out);

    out->append("

");
  }
}

std::string GetAppCacheManifestToRemove(const std::string& query) {
  if (!StartsWithASCII(query, "remove=", true)) {
    // Not a recognized format.
    return std::string();
  }
  std::string manifest_url_base64 = UnescapeURLComponent(
      query.substr(strlen("remove=")),
      UnescapeRule::NORMAL | UnescapeRule::URL_SPECIAL_CHARS);
  std::string manifest_url;
  base::Base64Decode(manifest_url_base64, &manifest_url);
  return manifest_url;
}

struct ManifestURLComparator {
 public:
  bool operator() (
      const appcache::AppCacheInfo& lhs,
      const appcache::AppCacheInfo& rhs) const {
    return (lhs.manifest_url.spec() < rhs.manifest_url.spec());
  }
} manifest_url_comparator;

}  // namespace

namespace appcache {

ViewAppCacheInternalsJob::ViewAppCacheInternalsJob(
    net::URLRequest* request,
    AppCacheService* service)
    : net::URLRequestSimpleJob(request),
      appcache_service_(service) {
}

ViewAppCacheInternalsJob::~ViewAppCacheInternalsJob() {
  // Cancel callback if job is destroyed before callback is called.
  if (appcache_done_callback_)
    appcache_done_callback_.release()->Cancel();
}

void ViewAppCacheInternalsJob::GetAppCacheInfoAsync() {
  info_collection_ = new AppCacheInfoCollection;
  appcache_done_callback_ =
      new net::CancelableCompletionCallback<ViewAppCacheInternalsJob>(
          this, &ViewAppCacheInternalsJob::AppCacheDone);
  appcache_service_->GetAllAppCacheInfo(
      info_collection_, appcache_done_callback_);
}

void ViewAppCacheInternalsJob::RemoveAppCacheInfoAsync(
    const std::string& manifest_url_spec) {
  appcache_done_callback_ =
      new net::CancelableCompletionCallback<ViewAppCacheInternalsJob>(
          this, &ViewAppCacheInternalsJob::AppCacheDone);

  GURL manifest(manifest_url_spec);
  appcache_service_->DeleteAppCacheGroup(
      manifest, appcache_done_callback_);
}

void ViewAppCacheInternalsJob::Start() {
  if (!request_)
    return;

  // Handle any remove appcache request, then redirect back to
  // the same URL stripped of query parameters. The redirect happens as part
  // of IsRedirectResponse().
  if (request_->url().has_query()) {
    std::string remove_appcache_manifest(
        GetAppCacheManifestToRemove(request_->url().query()));

    // Empty manifests are dealt with by the deleter.
    RemoveAppCacheInfoAsync(remove_appcache_manifest);
  } else {
    GetAppCacheInfoAsync();
  }
}

bool ViewAppCacheInternalsJob::IsRedirectResponse(
    GURL* location, int* http_status_code) {
  if (request_->url().has_query()) {
    // Strip the query parameters.
    GURL::Replacements replacements;
    replacements.ClearQuery();
    *location = request_->url().ReplaceComponents(replacements);
    *http_status_code = 307;
    return true;
  }
  return false;
}

void ViewAppCacheInternalsJob::GenerateHTMLAppCacheInfo(
    std::string* out) const {
  typedef std::map<GURL, AppCacheInfoVector> InfoByOrigin;
  AppCacheInfoVector appcaches;
  for (InfoByOrigin::const_iterator origin =
           info_collection_->infos_by_origin.begin();
       origin != info_collection_->infos_by_origin.end(); ++origin) {
    for (AppCacheInfoVector::const_iterator info =
             origin->second.begin(); info != origin->second.end(); ++info)
      appcaches.push_back(*info);
  }

  std::sort(appcaches.begin(), appcaches.end(), manifest_url_comparator);

  AddHTMLFromAppCacheToOutput(*appcache_service_, appcaches, out);
}

void ViewAppCacheInternalsJob::AppCacheDone(int rv) {
  appcache_done_callback_ = NULL;
  if (rv != net::OK)
    info_collection_ = NULL;
  StartAsync();
}

bool ViewAppCacheInternalsJob::GetData(std::string* mime_type,
                                       std::string* charset,
                                       std::string* data) const {
  mime_type->assign("text/html");
  charset->assign("UTF-8");

  data->clear();
  StartHTML(data);
  if (!info_collection_.get())
    data->append(kErrorMessage);
  else if (info_collection_->infos_by_origin.empty())
    data->append(kEmptyAppCachesMessage);
  else
    GenerateHTMLAppCacheInfo(data);
  EndHTML(data);
  return true;
}

}  // namespace appcache
<|endoftext|>


<commit_before>// The libMesh Finite Element Library.
// Copyright (C) 2002-2019 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

//
Subdomains Example 3 - Integrating discontinuous data that cuts the mesh

// \author Benjamin S. Kirk
// \date 2013

// C++ include files that we need
#include <iostream>
#include <algorithm>
#include <math.h>

// Basic include file needed for the mesh functionality.
#include "libmesh/libmesh.h"
#include "libmesh/mesh.h"
#include "libmesh/mesh_generation.h"
#include "libmesh/mesh_refinement.h"
#include "libmesh/quadrature_gauss.h"
#include "libmesh/quadrature_composite.h"
#include "libmesh/fe.h"
#include "libmesh/elem.h"

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

// declare the functions we will use
void integrate_function (const MeshBase & mesh);

// signed distance function
const Real radius = 0.5;

Real distance (const Point & p)
{
  Point cent(0.8, 0.9);
  return ((p-cent).norm() - radius);
}

Real integrand (const Point & p)
{
  return (distance(p) < 0) ? 10. : 1.;
}

// Begin the main program.
int main (int argc, char ** argv)
{
  // Initialize libMesh and any dependent libraries, like in example 2.
  LibMeshInit init (argc, argv);

  // This example requires Adaptive Mesh Refinement support - although
  // it only refines uniformly, the refinement code used is the same
  // underneath.  It also requires libmesh support for Triangle and
  // Tetgen, which means that libmesh must be configured with
  // --disable-strict-lgpl for this example to run.
#if !defined(LIBMESH_HAVE_TRIANGLE) || !defined(LIBMESH_HAVE_TETGEN) || !defined(LIBMESH_ENABLE_AMR)
  libmesh_example_requires(false, "--disable-strict-lgpl --enable-amr");
#else

  // Skip this 2D example if libMesh was compiled as 1D-only.
  libmesh_example_requires(2 <= LIBMESH_DIM, "2D support");

  // Read the mesh from file.  This is the coarse mesh that will be used
  // in example 10 to demonstrate adaptive mesh refinement.  Here we will
  // simply read it in and uniformly refine it 5 times before we compute
  // with it.
  Mesh mesh(init.comm());

  {
    unsigned int dim=2;

    if (argc == 3 && std::atoi(argv[2]) == 3)
      {
        libmesh_here();
        dim=3;
      }

    mesh.read ((dim==2) ? "mesh.xda" : "hybrid_3d.xda");
  }

  // Create a MeshRefinement object to handle refinement of our mesh.
  // This class handles all the details of mesh refinement and coarsening.
  MeshRefinement mesh_refinement (mesh);

  // Uniformly refine the mesh 4 times.  This is the
  // first time we use the mesh refinement capabilities
  // of the library.
  mesh_refinement.uniformly_refine (4);

  // Print information about the mesh to the screen.
  mesh.print_info();

  // integrate the desired function
  integrate_function (mesh);

  // All done.
  return 0;
#endif
}

void integrate_function (const MeshBase & mesh)
{
#if defined(LIBMESH_HAVE_TRIANGLE) && defined(LIBMESH_HAVE_TETGEN)

  std::vector<Real> vertex_distance;

  QComposite<QGauss> qrule (mesh.mesh_dimension(), FIRST);
  //QGauss qrule (mesh.mesh_dimension(), FIRST);

  std::unique_ptr<FEBase> fe (FEBase::build (mesh.mesh_dimension(), FEType (FIRST, LAGRANGE)));

  Real int_val=0.;

  const std::vector<Point> & q_points = fe->get_xyz();
  const std::vector<Real>  & JxW      = fe->get_JxW();

  for (const auto & elem : mesh.active_local_element_ptr_range())
    {
      vertex_distance.clear();

      for (unsigned int v=0; v<elem->n_vertices(); v++)
        vertex_distance.push_back (distance(elem->point(v)));

      qrule.init (*elem, vertex_distance);

      fe->reinit (elem,
                  &(qrule.get_points()),
                  &(qrule.get_weights()));

      // TODO:  would it be valuable to have the composite quadrature rule sort
      // from smallest to largest JxW value to help prevent
      // ... large + small + large + large + small ...
      // type truncation errors?
      for (std::size_t qp=0; qp<q_points.size(); qp++)
        int_val += JxW[qp] * integrand(q_points[qp]);
    }

  mesh.comm().sum (int_val);

  libMesh::out << "\n***********************************\n"
               << " int_val   = " << int_val << std::endl
               << " exact_val = " <<  1*(2*2 - radius*radius*pi) + 10.*(radius*radius*pi)
               << "\n***********************************\n"
               << std::endl;
#else
  libmesh_ignore(mesh);
#endif
}
<commit_msg>Directly include parallel.h where needed<commit_after>// The libMesh Finite Element Library.
// Copyright (C) 2002-2019 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

//
Subdomains Example 3 - Integrating discontinuous data that cuts the mesh

// \author Benjamin S. Kirk
// \date 2013

// C++ include files that we need
#include <iostream>
#include <algorithm>
#include <math.h>

// Basic include file needed for the mesh functionality.
#include "libmesh/libmesh.h"
#include "libmesh/mesh.h"
#include "libmesh/mesh_generation.h"
#include "libmesh/mesh_refinement.h"
#include "libmesh/quadrature_gauss.h"
#include "libmesh/quadrature_composite.h"
#include "libmesh/fe.h"
#include "libmesh/elem.h"
#include "libmesh/parallel.h"

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

// declare the functions we will use
void integrate_function (const MeshBase & mesh);

// signed distance function
const Real radius = 0.5;

Real distance (const Point & p)
{
  Point cent(0.8, 0.9);
  return ((p-cent).norm() - radius);
}

Real integrand (const Point & p)
{
  return (distance(p) < 0) ? 10. : 1.;
}

// Begin the main program.
int main (int argc, char ** argv)
{
  // Initialize libMesh and any dependent libraries, like in example 2.
  LibMeshInit init (argc, argv);

  // This example requires Adaptive Mesh Refinement support - although
  // it only refines uniformly, the refinement code used is the same
  // underneath.  It also requires libmesh support for Triangle and
  // Tetgen, which means that libmesh must be configured with
  // --disable-strict-lgpl for this example to run.
#if !defined(LIBMESH_HAVE_TRIANGLE) || !defined(LIBMESH_HAVE_TETGEN) || !defined(LIBMESH_ENABLE_AMR)
  libmesh_example_requires(false, "--disable-strict-lgpl --enable-amr");
#else

  // Skip this 2D example if libMesh was compiled as 1D-only.
  libmesh_example_requires(2 <= LIBMESH_DIM, "2D support");

  // Read the mesh from file.  This is the coarse mesh that will be used
  // in example 10 to demonstrate adaptive mesh refinement.  Here we will
  // simply read it in and uniformly refine it 5 times before we compute
  // with it.
  Mesh mesh(init.comm());

  {
    unsigned int dim=2;

    if (argc == 3 && std::atoi(argv[2]) == 3)
      {
        libmesh_here();
        dim=3;
      }

    mesh.read ((dim==2) ? "mesh.xda" : "hybrid_3d.xda");
  }

  // Create a MeshRefinement object to handle refinement of our mesh.
  // This class handles all the details of mesh refinement and coarsening.
  MeshRefinement mesh_refinement (mesh);

  // Uniformly refine the mesh 4 times.  This is the
  // first time we use the mesh refinement capabilities
  // of the library.
  mesh_refinement.uniformly_refine (4);

  // Print information about the mesh to the screen.
  mesh.print_info();

  // integrate the desired function
  integrate_function (mesh);

  // All done.
  return 0;
#endif
}

void integrate_function (const MeshBase & mesh)
{
#if defined(LIBMESH_HAVE_TRIANGLE) && defined(LIBMESH_HAVE_TETGEN)

  std::vector<Real> vertex_distance;

  QComposite<QGauss> qrule (mesh.mesh_dimension(), FIRST);
  //QGauss qrule (mesh.mesh_dimension(), FIRST);

  std::unique_ptr<FEBase> fe (FEBase::build (mesh.mesh_dimension(), FEType (FIRST, LAGRANGE)));

  Real int_val=0.;

  const std::vector<Point> & q_points = fe->get_xyz();
  const std::vector<Real>  & JxW      = fe->get_JxW();

  for (const auto & elem : mesh.active_local_element_ptr_range())
    {
      vertex_distance.clear();

      for (unsigned int v=0; v<elem->n_vertices(); v++)
        vertex_distance.push_back (distance(elem->point(v)));

      qrule.init (*elem, vertex_distance);

      fe->reinit (elem,
                  &(qrule.get_points()),
                  &(qrule.get_weights()));

      // TODO:  would it be valuable to have the composite quadrature rule sort
      // from smallest to largest JxW value to help prevent
      // ... large + small + large + large + small ...
      // type truncation errors?
      for (std::size_t qp=0; qp<q_points.size(); qp++)
        int_val += JxW[qp] * integrand(q_points[qp]);
    }

  mesh.comm().sum (int_val);

  libMesh::out << "\n***********************************\n"
               << " int_val   = " << int_val << std::endl
               << " exact_val = " <<  1*(2*2 - radius*radius*pi) + 10.*(radius*radius*pi)
               << "\n***********************************\n"
               << std::endl;
#else
  libmesh_ignore(mesh);
#endif
}
<|endoftext|>


<commit_before>/*
 * Copyright © 2017 Collabora Ltd.
 *
 * This file is part of vkmark.
 *
 * vkmark is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation, either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * vkmark is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with vkmark. If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *   Alexandros Frantzis <alexandros.frantzis@collabora.com>
 */

#include "window_system_loader.h"
#include "window_system.h"
#include "options.h"
#include <dlfcn.h>
#include <vector>
#include <string>
#include <algorithm>
#include <dirent.h>
#include <stdexcept>

namespace
{

using WindowSystemCreateFunc = std::unique_ptr<WindowSystem>(*)(Options const&);
using WindowSystemProbeFunc = int(*)();

void close_lib(void* handle)
{
    if (handle) dlclose(handle);
}

std::vector<std::string> files_in_dir(std::string dir)
{
    std::vector<std::string> files;

    auto const dirp = opendir(dir.c_str());

    if (dirp != nullptr)
    {
        dirent const* ent;

        while ((ent = readdir(dirp)) != nullptr)
            files.push_back(dir + "/" + ent->d_name);

        closedir(dirp);
    }

    return files;
}

}

WindowSystemLoader::WindowSystemLoader(Options const& options)
    : options{options},
      lib_handle{nullptr, close_lib}
{
}

WindowSystem& WindowSystemLoader::load_window_system()
{
    if (window_system)
        return *window_system;

    auto const lib = probe_for_best_window_system();

    lib_handle = LibHandle{dlopen(lib.c_str(), RTLD_LAZY), close_lib};

    auto const ws_create = reinterpret_cast<WindowSystemCreateFunc>(
        dlsym(lib_handle.get(), "vkmark_window_system_create"));

    if (!ws_create)
        throw std::runtime_error{"Selected window system module doesn't provide a create function"};

    window_system = ws_create(options);

    if (!window_system)
        throw std::runtime_error{"Selected window system module failed to create window system"};

    return *window_system;
}

std::string WindowSystemLoader::probe_for_best_window_system()
{
    std::vector<int> priorities;
    auto const candidates = files_in_dir(options.window_system_dir);

    for (auto const& c : candidates)
    {
        auto const handle = LibHandle{dlopen(c.c_str(), RTLD_LAZY), close_lib};
        if (handle.get())
        {
            auto ws_probe = reinterpret_cast<WindowSystemProbeFunc>(
                dlsym(handle.get(), "vkmark_window_system_probe"));
            if (ws_probe)
                priorities.push_back(ws_probe());
            else
                priorities.push_back(0);
        }
        else
        {
            priorities.push_back(0);
        }
    }

    auto const iter = std::max_element(priorities.begin(), priorities.end());
    if (iter != priorities.end() && *iter > 0)
    {
        auto const index = std::distance(priorities.begin(), iter);
        return candidates[index];
    }

    throw std::runtime_error{"Failed to find usable window system, try using --window-system-dir"};
}
<commit_msg>core: Improve window system module loading and add logging<commit_after>/*
 * Copyright © 2017 Collabora Ltd.
 *
 * This file is part of vkmark.
 *
 * vkmark is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation, either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * vkmark is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with vkmark. If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *   Alexandros Frantzis <alexandros.frantzis@collabora.com>
 */

#include "window_system_loader.h"
#include "window_system.h"
#include "options.h"
#include "log.h"

#include <dlfcn.h>
#include <vector>
#include <string>
#include <algorithm>
#include <dirent.h>
#include <stdexcept>

namespace
{

using WindowSystemCreateFunc = std::unique_ptr<WindowSystem>(*)(Options const&);
using WindowSystemProbeFunc = int(*)();

void close_lib(void* handle)
{
    if (handle) dlclose(handle);
}

bool has_shared_object_extension(std::string const& name)
{
    static std::string const so{".so"};

    return name.size() > so.size() &&
           std::equal(so.rbegin(), so.rend(), name.rbegin());
}

std::vector<std::string> files_in_dir(std::string dir)
{
    std::vector<std::string> files;

    auto const dirp = opendir(dir.c_str());

    if (dirp != nullptr)
    {
        dirent const* ent;

        while ((ent = readdir(dirp)) != nullptr)
        {
            if (has_shared_object_extension(ent->d_name))
                files.push_back(dir + "/" + ent->d_name);
        }

        closedir(dirp);
    }

    return files;
}

}

WindowSystemLoader::WindowSystemLoader(Options const& options)
    : options{options},
      lib_handle{nullptr, close_lib}
{
}

WindowSystem& WindowSystemLoader::load_window_system()
{
    if (window_system)
        return *window_system;

    auto const lib = probe_for_best_window_system();

    lib_handle = LibHandle{dlopen(lib.c_str(), RTLD_LAZY), close_lib};

    auto const ws_create = reinterpret_cast<WindowSystemCreateFunc>(
        dlsym(lib_handle.get(), "vkmark_window_system_create"));

    if (!ws_create)
        throw std::runtime_error{"Selected window system module doesn't provide a create function"};

    window_system = ws_create(options);

    if (!window_system)
        throw std::runtime_error{"Selected window system module failed to create window system"};

    return *window_system;
}

std::string WindowSystemLoader::probe_for_best_window_system()
{
    std::vector<int> priorities;

    Log::debug("WindowSystemLoader: Looking in %s for window system modules\n",
               options.window_system_dir.c_str());

    auto const candidates = files_in_dir(options.window_system_dir);

    for (auto const& c : candidates)
    {
        Log::debug("WindowSystemLoader: Probing %s... ", c.c_str());

        auto const handle = LibHandle{dlopen(c.c_str(), RTLD_LAZY), close_lib};
        if (handle.get())
        {
            auto ws_probe = reinterpret_cast<WindowSystemProbeFunc>(
                dlsym(handle.get(), "vkmark_window_system_probe"));
            if (ws_probe)
            {
                priorities.push_back(ws_probe());

                auto const fmt = Log::continuation_prefix + "succeeded with priority %d\n";
                Log::debug(fmt.c_str(), priorities.back());
            }
            else
            {
                priorities.push_back(0);

                auto const fmt = Log::continuation_prefix + "failed to find probe function: %s\n";
                Log::debug(fmt.c_str(), dlerror());
            }
        }
        else
        {
            priorities.push_back(0);

            auto const fmt = Log::continuation_prefix + "failed to load file: %s\n";
            Log::debug(fmt.c_str(), dlerror());
        }
    }

    auto const iter = std::max_element(priorities.begin(), priorities.end());
    if (iter != priorities.end() && *iter > 0)
    {
        auto const index = std::distance(priorities.begin(), iter);
        Log::debug("WindowSystemLoader: Selected window system module %s\n",
                   candidates[index].c_str());
        return candidates[index];
    }

    throw std::runtime_error{"Failed to find usable window system, try using --window-system-dir"};
}
<|endoftext|>


<commit_before>// biopore_drain.C --- Static vertical biopores that ends in drain pipes.
//
// Copyright 2008 Per Abrahamsen and KU.
//
// This file is part of Daisy.
//
// Daisy is free software; you can redistribute it and/or modify
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// Daisy is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser Public License for more details.
//
// You should have received a copy of the GNU Lesser Public License
// along with Daisy; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

#define BUILD_DLL

#include "biopore.h"
#include "block.h"
#include "vcheck.h"
#include "librarian.h"
#include "submodeler.h"
#include "check.h"
#include "geometry.h"
#include "soil.h"
#include "soil_heat.h"
#include "anystate.h"
#include "chemical.h"
#include "groundwater.h"
#include <sstream>

// The 'drain' model.

struct BioporeDrain : public Biopore
{
  // Parameters.
  /* const */ double pipe_position;   // [cm]

  // State
  Anystate get_state () const
  { return Anystate::none (); }
  void set_state (const Anystate&)
  { }

  // Simulation.
  double total_water () const
  { return 0.0; }
  void get_solute (IM&) const
  { }
  double air_bottom (size_t) const    // Lowest point with air [cm]
  { return pipe_position; }

  double capacity (const Geometry& geo, size_t e, const double dt) const
  { return max_infiltration_rate (geo, e) * dt; }
  void infiltrate (const Geometry&, size_t, double /* [cm] */)
  { }

  double matrix_biopore_drain (size_t c, const Geometry& geo,
                               const Soil& soil, bool active,
                               const double h_barrier, double pressure_end,
                               double K_xx, double h) const;
  void update_matrix_sink (const Geometry& geo,
                           const Soil& soil,
                           const SoilHeat& soil_heat,
                           const std::vector<bool>& active,
                           const double h_barrier,
                           const double pressure_initiate,
                           const double pressure_end,
                           const std::vector<double>& h, const double dt);
  void update_water ()
  { }
  void add_to_sink (std::vector<double>&,
                    std::vector<double>& S_drain) const
  {
    const size_t cell_size = S.size ();
    daisy_assert (S_drain.size () == cell_size);
    for (size_t c = 0; c < cell_size; c++)
      S_drain[c] += S[c];
  }
  void add_solute (symbol, size_t, const double)
  { }
  void matrix_solute (const Geometry&, const double,
                      const Chemical&, std::vector<double>&,
                      Treelog&)
  { /* Handled by S_drain. */ }
  void output (Log& log) const
  { output_base (log); }

  // Create and Destroy.
  bool initialize (const Units& units, const Geometry& geo, const Scope& scope,
                   const Groundwater& groundwater, Treelog& msg)
  {
    bool ok = initialize_base (units, geo, scope, msg);
    if (pipe_position > 0)
      {
        if (groundwater.is_pipe ())
          // Pipe height not specified here, use value from column.
          pipe_position = groundwater.pipe_height ();
        else
          {
            msg.error ("Unknown pipe position");
            ok = false;
          }
      }
    return ok;
  }
  bool check (const Geometry& geo, Treelog& msg) const
  { return check_base (geo, msg); }
  BioporeDrain (Block& al);
};

double
BioporeDrain::matrix_biopore_drain (size_t c, const Geometry& geo,
                                    const Soil& soil, bool active,
                                    const double h_barrier,
                                    const double pressure_end,
                                    double K_xx, double h) const
{
  const double M_c = density_cell[c];
  if (!std::isnormal (M_c))
    // No biopores here.
    return 0.0;
  const double r_c = diameter / 2.0;
  const double h_3 = air_bottom (c) - geo.cell_z (c);

  double S;
  if (active && h>h_3 + h_barrier)
    {
      // The largest pressure gradient between the domains are
      // pressure_end, above that we claim air will disrupt the suction.
      const double h_3_suck = std::max (h_3, h + pressure_end);
      S = matrix_to_biopore (K_xx, M_c, r_c, h, h_3_suck)
        * geo.fraction_in_z_interval (c, height_start, height_end);
    }
  else
    S = 0.0;
  return S;
}

void
BioporeDrain::update_matrix_sink (const Geometry& geo,
                                  const Soil& soil,
                                  const SoilHeat& soil_heat,
                                  const std::vector<bool>& active,
                                  const double h_barrier,
                                  const double pressure_initiate,
                                  const double pressure_end,
                                  const std::vector<double>& h,
                                  const double /* dt */)
{
  const size_t cell_size = geo.cell_size ();
  for (size_t c = 0; c < cell_size; c++)
    {
      const double h_cond = std::min(pressure_initiate, h[c]);
      const double T = soil_heat.T (c);
      const double h_ice = 0.0;    //ice ignored
      const double K_zz = soil.K (c, h_cond, h_ice, T);
      const double K_xx = K_zz * soil.anisotropy (c);
      S[c] = matrix_biopore_drain (c, geo, soil, active[c], h_barrier,
                                   pressure_end, K_xx, h[c]);
    }
}

template <class T>
std::string stringify (const T& x)
{
  std::ostringstream tmp;
  tmp << x;
  return tmp.str ();
}

#define TREELOG_INDEX(msg, key, index) \
  Treelog::Open nest (msg, stringify (key) + " = " + stringify (index))

#define TREELOG_MODEL1(msg) \
  Treelog::Open nest (msg, this->library_id () + ": " + this->name \
                      + " " + __FUNCTION__)

#if 0
void
BioporeDrain::matrix_solute (const Geometry& geo, const double dt,
                             const Chemical& chemical,
                             std::vector<double>& source_chem,
                             Treelog& msg)
{
  TREELOG_MODEL1 (msg);
  const symbol chem = chemical.name;
  const size_t cell_size = geo.cell_size ();
  daisy_assert (source_chem.size () == cell_size);

  // From matrix to biopore.
  for (size_t c = 0; c < cell_size; c++)
    {
      TREELOG_INDEX (msg, "cell", c);
      const double water_sink = S[c]; // [cm^3 W/cm^3 S/h]
      daisy_assert (water_sink >= 0.0);
      const double C = chemical.C_secondary (c); // [g/cm^3 W]
      source_chem[c] -= water_sink * C; // [g/cm^3 S/h]
      if (!iszero (source_chem[c]))
        {
          std::stringstream tmp;
          tmp << "soruce_chem = " << source_chem[c] << ", S = " << S[c]
              << ", C = " << C;
          msg.message (tmp.str ());
        }
    }

}
#endif

BioporeDrain::BioporeDrain (Block& al)
  : Biopore (al),
    pipe_position (al.number ("pipe_position", 42.42e42))
{ }

static struct BioporeDrainSyntax
{
  static Model& make (Block& al)
  { return *new BioporeDrain (al); }

  BioporeDrainSyntax ()
  {
    Syntax& syntax = *new Syntax ();
    AttributeList& alist = *new AttributeList ();
    alist.add ("description", "Biopores that ends in the drain pipes.");
    Biopore::load_base (syntax, alist);

    syntax.add ("pipe_position", "cm", Check::negative (), Syntax::Const,
                "Height pipes are placed in the soil (a negative number).\n\
By default, use the height specified for pipes in the column.");
    Librarian::add_type (Biopore::component, "drain", alist, syntax, &make);
  }
} BioporeDrain_syntax;

// biopore_drain.C ends here.
<commit_msg><commit_after>// biopore_drain.C --- Static vertical biopores that ends in drain pipes.
//
// Copyright 2008 Per Abrahamsen and KU.
//
// This file is part of Daisy.
//
// Daisy is free software; you can redistribute it and/or modify
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// Daisy is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser Public License for more details.
//
// You should have received a copy of the GNU Lesser Public License
// along with Daisy; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

#define BUILD_DLL

#include "biopore.h"
#include "block.h"
#include "vcheck.h"
#include "librarian.h"
#include "submodeler.h"
#include "check.h"
#include "geometry.h"
#include "soil.h"
#include "soil_heat.h"
#include "anystate.h"
#include "chemical.h"
#include "groundwater.h"
#include <sstream>

// The 'drain' model.

struct BioporeDrain : public Biopore
{
  // Parameters.
  /* const */ double pipe_position;   // [cm]

  // State
  Anystate get_state () const
  { return Anystate::none (); }
  void set_state (const Anystate&)
  { }

  // Simulation.
  double total_water () const
  { return 0.0; }
  void get_solute (IM&) const
  { }
  double air_bottom (size_t) const    // Lowest point with air [cm]
  { return pipe_position; }

  double capacity (const Geometry& geo, size_t e, const double dt) const
  { return max_infiltration_rate (geo, e) * dt; }
  void infiltrate (const Geometry&, size_t, double /* [cm] */)
  { }

  double matrix_biopore_drain (size_t c, const Geometry& geo,
                               const Soil& soil, bool active,
                               const double h_barrier, double pressure_end,
                               double K_xx, double h) const;
  void update_matrix_sink (const Geometry& geo,
                           const Soil& soil,
                           const SoilHeat& soil_heat,
                           const std::vector<bool>& active,
                           const double h_barrier,
                           const double pressure_initiate,
                           const double pressure_end,
                           const std::vector<double>& h, const double dt);
  void update_water ()
  { }
  void add_to_sink (std::vector<double>&,
                    std::vector<double>& S_drain) const
  {
    const size_t cell_size = S.size ();
    daisy_assert (S_drain.size () == cell_size);
    for (size_t c = 0; c < cell_size; c++)
      S_drain[c] += S[c];
  }
  void add_solute (symbol, size_t, const double)
  { }
  void matrix_solute (const Geometry&, const double,
                      const Chemical&, std::vector<double>&,
                      Treelog&)
  { /* Handled by S_drain. */ }
  void output (Log& log) const
  { output_base (log); }

  // Create and Destroy.
  bool initialize (const Units& units, const Geometry& geo, const Scope& scope,
                   const Groundwater& groundwater, Treelog& msg)
  {
    bool ok = initialize_base (units, geo, scope, msg);
    if (pipe_position > 0)
      {
        if (groundwater.is_pipe ())
          // Pipe height not specified here, use value from column.
          pipe_position = groundwater.pipe_height ();
        else
          {
            msg.error ("Unknown pipe position");
            ok = false;
          }
      }
    return ok;
  }
  bool check (const Geometry& geo, Treelog& msg) const
  { return check_base (geo, msg); }
  BioporeDrain (Block& al);
};

double
BioporeDrain::matrix_biopore_drain (size_t c, const Geometry& geo,
                                    const Soil& soil, bool active,
                                    const double h_barrier,
                                    const double pressure_end,
                                    double K_xx, double h) const
{
  const double M_c = density_cell[c];
  if (!std::isnormal (M_c))
    // No biopores here.
    return 0.0;
  const double r_c = diameter / 2.0;
  const double h_3 = air_bottom (c) - geo.cell_z (c);

  double S;
  if (active && h>h_3 + h_barrier)
    {
      // The largest pressure gradient between the domains are
      // pressure_end, above that we claim air will disrupt the suction.
      const double h_3_suck = std::max (h_3, h + pressure_end);

      S = matrix_to_biopore (K_xx, M_c, r_c, h, h_3_suck)
        * geo.fraction_in_z_interval (c, height_start, height_end);
    }
  else
    S = 0.0;
  return S;
}

void
BioporeDrain::update_matrix_sink (const Geometry& geo,
                                  const Soil& soil,
                                  const SoilHeat& soil_heat,
                                  const std::vector<bool>& active,
                                  const double h_barrier,
                                  const double pressure_initiate,
                                  const double pressure_end,
                                  const std::vector<double>& h,
                                  const double /* dt */)
{
  const size_t cell_size = geo.cell_size ();
  for (size_t c = 0; c < cell_size; c++)
    {
      const double h_cond = std::min(pressure_initiate, h[c]);
      const double T = soil_heat.T (c);
      const double h_ice = 0.0;    //ice ignored
      const double K_zz = soil.K (c, h_cond, h_ice, T);
      const double K_xx = K_zz * soil.anisotropy (c);
      S[c] = matrix_biopore_drain (c, geo, soil, active[c], h_barrier,
                                   pressure_end, K_xx, h[c]);
    }
}

template <class T>
std::string stringify (const T& x)
{
  std::ostringstream tmp;
  tmp << x;
  return tmp.str ();
}

#define TREELOG_INDEX(msg, key, index) \
  Treelog::Open nest (msg, stringify (key) + " = " + stringify (index))

#define TREELOG_MODEL1(msg) \
  Treelog::Open nest (msg, this->library_id () + ": " + this->name \
                      + " " + __FUNCTION__)

#if 0
void
BioporeDrain::matrix_solute (const Geometry& geo, const double dt,
                             const Chemical& chemical,
                             std::vector<double>& source_chem,
                             Treelog& msg)
{
  TREELOG_MODEL1 (msg);
  const symbol chem = chemical.name;
  const size_t cell_size = geo.cell_size ();
  daisy_assert (source_chem.size () == cell_size);

  // From matrix to biopore.
  for (size_t c = 0; c < cell_size; c++)
    {
      TREELOG_INDEX (msg, "cell", c);
      const double water_sink = S[c]; // [cm^3 W/cm^3 S/h]
      daisy_assert (water_sink >= 0.0);
      const double C = chemical.C_secondary (c); // [g/cm^3 W]
      source_chem[c] -= water_sink * C; // [g/cm^3 S/h]
      if (!iszero (source_chem[c]))
        {
          std::stringstream tmp;
          tmp << "soruce_chem = " << source_chem[c] << ", S = " << S[c]
              << ", C = " << C;
          msg.message (tmp.str ());
        }
    }

}
#endif

BioporeDrain::BioporeDrain (Block& al)
  : Biopore (al),
    pipe_position (al.number ("pipe_position", 42.42e42))
{ }

static struct BioporeDrainSyntax
{
  static Model& make (Block& al)
  { return *new BioporeDrain (al); }

  BioporeDrainSyntax ()
  {
    Syntax& syntax = *new Syntax ();
    AttributeList& alist = *new AttributeList ();
    alist.add ("description", "Biopores that ends in the drain pipes.");
    Biopore::load_base (syntax, alist);

    syntax.add ("pipe_position", "cm", Check::negative (), Syntax::Const,
                "Height pipes are placed in the soil (a negative number).\n\
By default, use the height specified for pipes in the column.");
    Librarian::add_type (Biopore::component, "drain", alist, syntax, &make);
  }
} BioporeDrain_syntax;

// biopore_drain.C ends here.
<|endoftext|>