<commit_before>#ifndef STAN_MATH_MIX_MAT_FUNCTOR_FINITE_DIFF_GRAD_HESSIAN_HPP
#define STAN_MATH_MIX_MAT_FUNCTOR_FINITE_DIFF_GRAD_HESSIAN_HPP

#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <vector>
#include <stan/math/rev/core.hpp>
#include <stan/math/mix/mat/functor/hessian.hpp>

namespace stan {

  namespace agrad {

    /**
     * Calculate the value and the gradient of the hessian of the specified
     * function at the specified argument using second-order autodiff and
       * first-order finite difference.
     *
     *
The functor must implement
     *
     *
     * double
     * operator()(const
     * Eigen::Matrix<double, Eigen::Dynamic, 1>&)
     *
     *
     * Reference:
     *
     * De Levie: An improved numerical approximation
     * for the first derivative, page 3
     *
     * 4 calls to the function, f.
     *
     * @tparam F Type of function
     * @param[in] f Function
     * @param[in] x Argument to function
     * @param[out] fx Function applied to argument
     * @param[out] grad_hess_fx gradient of Hessian of function at argument
     * @param[in] epsilon perturbation size
     */
    template <typename F>
    void
    finite_diff_grad_hessian(const F& f,
                             const Eigen::Matrix<double, -1, 1>& x,
                             double& fx,
                             Eigen::Matrix<double, -1, -1>& hess,
                             std::vector<Eigen::Matrix<double, -1, -1> >& grad_hess_fx,
                             const double epsilon = 1e-04) {
      using Eigen::Matrix;
      using Eigen::Dynamic;

      int d = x.size();
      double dummy_fx_eval;

      Matrix<double, Dynamic, 1> x_temp(x);
      Matrix<double, Dynamic, 1> grad_auto(d);
      Matrix<double, Dynamic, Dynamic> hess_auto(d, d);
      Matrix<double, Dynamic, Dynamic> hess_diff(d, d);

      hessian(f, x, fx, grad_auto, hess);
      for (int i = 0; i < d; ++i) {
        hess_diff.setZero();

        x_temp(i) = x(i) + 2.0 * epsilon;
        hessian(f, x_temp, dummy_fx_eval, grad_auto, hess_auto);
        hess_diff = -hess_auto;

        x_temp(i) = x(i) + -2.0 * epsilon;
        hessian(f, x_temp, dummy_fx_eval, grad_auto, hess_auto);
        hess_diff += hess_auto;

        x_temp(i) = x(i) + epsilon;
        hessian(f, x_temp, dummy_fx_eval, grad_auto, hess_auto);
        hess_diff += 8.0 * hess_auto;

        x_temp(i) = x(i) + -epsilon;
        hessian(f, x_temp, dummy_fx_eval, grad_auto, hess_auto);
        hess_diff -= 8.0 * hess_auto;

        x_temp(i) = x(i);
        hess_diff /= 12.0 * epsilon;

        grad_hess_fx.push_back(hess_diff);
      }
      fx = f(x);
    }

  }
}
#endif
<commit_msg>b f/i-1271 last cpplint warning<commit_after>#ifndef STAN_MATH_MIX_MAT_FUNCTOR_FINITE_DIFF_GRAD_HESSIAN_HPP
#define STAN_MATH_MIX_MAT_FUNCTOR_FINITE_DIFF_GRAD_HESSIAN_HPP

#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <stan/math/rev/core.hpp>
#include <stan/math/mix/mat/functor/hessian.hpp>
#include <vector>

namespace stan {

  namespace agrad {

    /**
     * Calculate the value and the gradient of the hessian of the specified
     * function at the specified argument using second-order autodiff and
       * first-order finite difference.
     *
     *
The functor must implement
     *
     *
     * double
     * operator()(const
     * Eigen::Matrix<double, Eigen::Dynamic, 1>&)
     *
     *
     * Reference:
     *
     * De Levie: An improved numerical approximation
     * for the first derivative, page 3
     *
     * 4 calls to the function, f.
     *
     * @tparam F Type of function
     * @param[in] f Function
     * @param[in] x Argument to function
     * @param[out] fx Function applied to argument
     * @param[out] grad_hess_fx gradient of Hessian of function at argument
     * @param[in] epsilon perturbation size
     */
    template <typename F>
    void
    finite_diff_grad_hessian(const F& f,
                             const Eigen::Matrix<double, -1, 1>& x,
                             double& fx,
                             Eigen::Matrix<double, -1, -1>& hess,
                             std::vector<Eigen::Matrix<double, -1, -1> >& grad_hess_fx,
                             const double epsilon = 1e-04) {
      using Eigen::Matrix;
      using Eigen::Dynamic;

      int d = x.size();
      double dummy_fx_eval;

      Matrix<double, Dynamic, 1> x_temp(x);
      Matrix<double, Dynamic, 1> grad_auto(d);
      Matrix<double, Dynamic, Dynamic> hess_auto(d, d);
      Matrix<double, Dynamic, Dynamic> hess_diff(d, d);

      hessian(f, x, fx, grad_auto, hess);
      for (int i = 0; i < d; ++i) {
        hess_diff.setZero();

        x_temp(i) = x(i) + 2.0 * epsilon;
        hessian(f, x_temp, dummy_fx_eval, grad_auto, hess_auto);
        hess_diff = -hess_auto;

        x_temp(i) = x(i) + -2.0 * epsilon;
        hessian(f, x_temp, dummy_fx_eval, grad_auto, hess_auto);
        hess_diff += hess_auto;

        x_temp(i) = x(i) + epsilon;
        hessian(f, x_temp, dummy_fx_eval, grad_auto, hess_auto);
        hess_diff += 8.0 * hess_auto;

        x_temp(i) = x(i) + -epsilon;
        hessian(f, x_temp, dummy_fx_eval, grad_auto, hess_auto);
        hess_diff -= 8.0 * hess_auto;

        x_temp(i) = x(i);
        hess_diff /= 12.0 * epsilon;

        grad_hess_fx.push_back(hess_diff);
      }
      fx = f(x);
    }

  }
}
#endif
<|endoftext|>


<commit_before>/* Copyright 2016-2017 CyberTech Labs Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */

#include <QtCore/QTimer>
#include <QtCore/QEventLoop>

#include <QtCore/QThread>

#include <trikKitInterpreterCommon/trikbrick.h>

#include <utils/abstractTimer.h>
#include <kitBase/robotModel/robotModelUtils.h>
#include <trikKit/robotModel/parts/trikShell.h>
#include <trikKit/robotModel/parts/trikLineSensor.h>
#include <kitBase/robotModel/robotParts/gyroscopeSensor.h>
#include <kitBase/robotModel/robotParts/encoderSensor.h>
#include <kitBase/robotModel/robotParts/random.h>
#include <kitBase/robotModel/robotParts/random.h>
#include <twoDModel/robotModel/parts/marker.h>
#include <twoDModel/engine/model/timeline.h>
///todo: temporary
#include <trikKitInterpreterCommon/robotModel/twoD/parts/twoDDisplay.h>

using namespace trik;

TrikBrick::TrikBrick(const QSharedPointer<robotModel::twoD::TrikTwoDRobotModel> &model)
	: mTwoDRobotModel(model)
	, mDisplay(model)
	, mKeys(model)
	, mSensorUpdater(model->timeline().produceTimer())
{
	connect(this, &TrikBrick::log, this, &TrikBrick::printToShell);
	mSensorUpdater->setRepeatable(true);
	mSensorUpdater->setInterval(model->updateIntervalForInterpretation()); // seems to be x2 of timeline tick
	connect(mSensorUpdater.data(), &utils::AbstractTimer::timeout, [model](){
		model->updateSensorsValues(); /// @todo: maybe connect to model directly?
	});
}

TrikBrick::~TrikBrick()
{
	qDeleteAll(mMotors);
	qDeleteAll(mSensors);
	qDeleteAll(mEncoders);
	qDeleteAll(mLineSensors);
	qDeleteAll(mTimers);
}

void TrikBrick::reset()
{
	mKeys.reset();///@todo: reset motos/device maps?
	//mDisplay.reset(); - is actually needed? Crashes app at exit
	emit stopWaiting();
	for (const auto &m : mMotors) {
		m->powerOff();
	}
	for (const auto &e : mEncoders) {
		e->reset();
	}
	for (const auto &t : mTimers) {
		t->stop();
	}
	qDeleteAll(mTimers);
	mTimers.clear();
	QMetaObject::invokeMethod(mSensorUpdater.data(), "stop"); // failproof against timer manipulation in another thread
}

void TrikBrick::printToShell(const QString &msg)
{
	using namespace kitBase::robotModel;
	using namespace trik::robotModel;
	parts::TrikShell* sh = RobotModelUtils::findDevice<parts::TrikShell>(*mTwoDRobotModel, "ShellPort");
	if (sh == nullptr) {
		qDebug("Error: 2d model shell part was not found");
		return;
	}
	sh->print(msg);
}

void TrikBrick::init()
{
	mDisplay.init();
//	for (const auto &m : mMotors) {
//		m->powerOff();
//	}
//	for (const auto &e : mEncoders) {
//		e->read();
//	}
//	for (const auto &s : mSensors) {
//		s->read();
//	}
	mTwoDRobotModel->updateSensorsValues();
	mMotors.clear(); // needed? reset?
	mSensors.clear();
	mEncoders.clear();
	mKeys.init();
	mGyroscope.reset(); // for some reason it won't reconnect to the robot parts otherwise.
	QMetaObject::invokeMethod(mSensorUpdater.data(), "start"); // failproof against timer manipulation in another thread
	//mSensorUpdater.start();
}

void TrikBrick::setCurrentDir(const QString &dir)
{
	mCurrentDir = QFileInfo(dir).dir(); // maybe can be constructed directly
}

void TrikBrick::setCurrentInputs(const QString &f)
{
	mIsExcerciseMode = true;
	if (f.isEmpty()) {
		return; // no inputs has been passed, no need to complain
	}
	QString file(f);
	QFile in(file);
	if (!in.open(QIODevice::ReadOnly | QIODevice::Text)) {
		emit warning(tr("Trying to read from file %1 failed").arg(file)); // todo: remove? It's only in exercise.
		//not really an error, usually
	}

	QStringList result;

	while (!in.atEnd()) {
		const auto line = in.readLine();
		result << QString::fromUtf8(line);
	}

	mInputs = result;
}

void TrikBrick::say(const QString &msg) {
	using namespace kitBase::robotModel;
	using namespace trik::robotModel;
	parts::TrikShell* sh = RobotModelUtils::findDevice<parts::TrikShell>(*mTwoDRobotModel, "ShellPort");
	if (sh == nullptr) {
		qDebug("Error: 2d model shell part was not found");
		return;
	}
	QMetaObject::invokeMethod(sh, "say", Q_ARG(const QString &, msg));
}

void TrikBrick::stop() {
	/// @todo: properly implement this?
	mTwoDRobotModel->stopRobot();
//	for (const auto &m : mMotors) {
//		m->powerOff();
//	}
//	for (const auto &e : mEncoders) {
//		e->reset();
//	}
}

trikControl::MotorInterface *TrikBrick::motor(const QString &port)
{
	using namespace kitBase::robotModel;
	if (!mMotors.contains(port)) {
		robotParts::Motor * mot =
				RobotModelUtils::findDevice<robotParts::Motor>(*mTwoDRobotModel, port);
		if (mot == nullptr) {
			emit error(tr("No configured motor on port: %1").arg(port));
			return nullptr;
		}
		mMotors[port] = new TrikMotorEmu(mot);
	}
	return mMotors[port];
}

trikControl::MarkerInterface *TrikBrick::marker()
{
	kitBase::robotModel::PortInfo markerPort = kitBase::robotModel::RobotModelUtils::findPort(*mTwoDRobotModel
			, "MarkerPort"
			, kitBase::robotModel::Direction::output);
	if (markerPort.isValid()) {
		using Marker = twoDModel::robotModel::parts::Marker;
		Marker* marker = kitBase::robotModel::RobotModelUtils::findDevice<Marker>(*mTwoDRobotModel, markerPort);
		mTrikProxyMarker.reset(new TrikProxyMarker(marker));
		return mTrikProxyMarker.data();
	}

	return nullptr;
}

trikControl::SensorInterface *TrikBrick::sensor(const QString &port)
{
	//testing
	using namespace kitBase::robotModel;
	if (!mSensors.contains(port)) {
		robotParts::ScalarSensor * sens =
				RobotModelUtils::findDevice<robotParts::ScalarSensor>(*mTwoDRobotModel, port);
		if (sens == nullptr) {
			emit error(tr("No configured sensor on port: %1").arg(port));
			return nullptr;
		}
		mSensors[port] = new TrikSensorEmu(sens);
	}
	return mSensors[port];
}

QStringList TrikBrick::motorPorts(trikControl::MotorInterface::Type type) const
{
	Q_UNUSED(type)
//	QLOG_INFO() << "Motor type is ignored";
	return mMotors.keys();
}

QStringList TrikBrick::sensorPorts(trikControl::SensorInterface::Type type) const
{
	Q_UNUSED(type)
//	QLOG_INFO() << "Sensor type is ignored";
	return mMotors.keys();
}

QStringList TrikBrick::encoderPorts() const {
	return mEncoders.keys();
}

trikControl::VectorSensorInterface *TrikBrick::accelerometer() {
	using namespace kitBase::robotModel;
	if (mAccelerometer.isNull()) {
		auto a = RobotModelUtils::findDevice<robotParts::AccelerometerSensor>(*mTwoDRobotModel
				, "AccelerometerPort");
		if (a == nullptr) {
			emit error(tr("No configured accelerometer"));
			return nullptr;
		}
		mAccelerometer.reset(new TrikAccelerometerAdapter(a));
	}

	return mAccelerometer.data();
}

trikControl::GyroSensorInterface *TrikBrick::gyroscope() {
	using namespace kitBase::robotModel;
	if (mGyroscope.isNull()) {
		auto a = RobotModelUtils::findDevice<robotParts::GyroscopeSensor>(*mTwoDRobotModel
				, "GyroscopePort");
		if (a == nullptr) {
			emit error(tr("No configured gyroscope"));
			return nullptr;
		}
		mGyroscope.reset(new TrikGyroscopeAdapter(a, mTwoDRobotModel));
	}

	return mGyroscope.data();
}

trikControl::LineSensorInterface *TrikBrick::lineSensor(const QString &port) {
	using namespace trik::robotModel::parts;
	using namespace kitBase::robotModel;
	if (port == "video0") {
		return lineSensor("LineSensorPort"); // seems to be the case for 2d model
	}

	if (!mLineSensors.contains(port)) {
		TrikLineSensor * sens =
				RobotModelUtils::findDevice<TrikLineSensor>(*mTwoDRobotModel, port);
		if (sens == nullptr) {
			emit error(tr("No configured LineSensor on port: %1").arg(port));
			return nullptr;
		}
		mLineSensors[port] = new TrikLineSensorAdapter(sens);
	}

	return mLineSensors[port];
}

trikControl::EncoderInterface *TrikBrick::encoder(const QString &port) {
	using namespace kitBase::robotModel;
	if (!mEncoders.contains(port)) {
		robotParts::EncoderSensor * enc =
				RobotModelUtils::findDevice<robotParts::EncoderSensor>(*mTwoDRobotModel, port);
		if (enc == nullptr) {
			emit error(tr("No configured encoder on port: %1").arg(port));
			return nullptr;
		}

		mEncoders[port] = new TrikEncoderAdapter(enc->port(), mTwoDRobotModel->engine());
	}

	return mEncoders[port];
}

trikControl::DisplayInterface *TrikBrick::display()
{
//	trik::robotModel::parts::TrikDisplay * const display =
//			kitBase::robotModel::RobotModelUtils::findDevice<trik::robotModel::parts::TrikDisplay>(*mTwoDRobotModel
//					, "DisplayPort");
//	if (display) {
//		bool res = QMetaObject::invokeMethod(display,
//		"drawSmile",
//		Qt::QueuedConnection, // connection type, auto?
//		Q_ARG(bool, false));
//		//display->drawSmile(false);
//		printf(res ? "true" : "false");
//	}
//	return nullptr;
	return &mDisplay;
}

trikControl::LedInterface *TrikBrick::led() {
	using namespace trik::robotModel::parts;
	using namespace kitBase::robotModel;
	if (mLed.isNull()) {
		auto l = RobotModelUtils::findDevice<TrikLed>(*mTwoDRobotModel, "LedPort");
		if (l == nullptr) {
			emit error(tr("No configured led"));
			return nullptr;
		}
		mLed.reset(new TrikLedAdapter(l));
	}

	return mLed.data();
}

int TrikBrick::random(int from, int to)
{
	using namespace kitBase::robotModel;
	auto r = RobotModelUtils::findDevice<robotParts::Random>(*mTwoDRobotModel, "RandomPort");
	// maybe store it later, like the others
	if (!r) {
		emit error(tr("No cofigured random device"));
		return -1;
	}

	return r->random(from, to);
}

void TrikBrick::wait(int milliseconds)
{
	QEventLoop loop;
	auto &timeline = dynamic_cast<twoDModel::model::Timeline &> (mTwoDRobotModel->timeline());

	if (timeline.isStarted()) {
		QScopedPointer<utils::AbstractTimer> t(timeline.produceTimer());
		QTimer abortTimer;
		QMetaObject::Connection abortConnection;

		auto mainHandler = [this, &t, &loop, &timeline, &abortConnection]() {
			disconnect(abortConnection);
			disconnect(this, &TrikBrick::stopWaiting, nullptr, nullptr);
			disconnect(&timeline, &twoDModel::model::Timeline::beforeStop, nullptr, nullptr);
			disconnect(t.data(), &utils::AbstractTimer::timeout, nullptr, nullptr);
			loop.quit();
		};

		auto abortHandler = [mainHandler, &timeline]() {
			if (!timeline.isStarted()) {
				mainHandler();
			}
		};

		connect(t.data(), &utils::AbstractTimer::timeout, mainHandler);
		connect(this, &TrikBrick::stopWaiting, mainHandler);

		// timers that are produced by produceTimer() doesn't use stop singal
		// be careful, one who use just utils::AbstractTimer can stuck
		connect(&timeline, &twoDModel::model::Timeline::beforeStop, mainHandler);
		abortConnection = connect(&abortTimer, &QTimer::timeout, abortHandler);

		// because timer is depends on twoDModel::model::Timeline
		if (timeline.isStarted()) {
			t->start(milliseconds);
			abortTimer.start(10);
			loop.exec();
		} else {
			mainHandler();
		}
	}
}

quint64 TrikBrick::time() const
{
	return mTwoDRobotModel->timeline().timestamp();
}

QStringList TrikBrick::readAll(const QString &path)
{
	if (mIsExcerciseMode) {
		return mInputs;
	}
	//if (mCurrentDir) todo: check that the current working dir is a save dir
	QFileInfo normalizedPath(mCurrentDir.absoluteFilePath(path)); // absoluteDir?
	QString file = normalizedPath.filePath();
	QFile in(file);
	if (!in.open(QIODevice::ReadOnly | QIODevice::Text)) {
		emit error(tr("Trying to read from file %1 failed").arg(file));
		return {};
	}

	QStringList result;

	while (!in.atEnd()) {
		const auto line = in.readLine();
		result << QString::fromUtf8(line);
	}

	return result;
}

utils::AbstractTimer *TrikBrick::timer(int milliseconds)
{
	utils::AbstractTimer *result = mTwoDRobotModel->timeline().produceTimer();
	mTimers.append(result);
	result->setRepeatable(true); // seems to be the case
	result->start(milliseconds);
	return result;
}

<commit_msg>Fix stack (local vars) access after return, that happend from ::timout signal handler sometimes<commit_after>/* Copyright 2016-2017 CyberTech Labs Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */

#include <QtCore/QTimer>
#include <QtCore/QEventLoop>

#include <QtCore/QThread>

#include <trikKitInterpreterCommon/trikbrick.h>

#include <utils/abstractTimer.h>
#include <kitBase/robotModel/robotModelUtils.h>
#include <trikKit/robotModel/parts/trikShell.h>
#include <trikKit/robotModel/parts/trikLineSensor.h>
#include <kitBase/robotModel/robotParts/gyroscopeSensor.h>
#include <kitBase/robotModel/robotParts/encoderSensor.h>
#include <kitBase/robotModel/robotParts/random.h>
#include <kitBase/robotModel/robotParts/random.h>
#include <twoDModel/robotModel/parts/marker.h>
#include <twoDModel/engine/model/timeline.h>
///todo: temporary
#include <trikKitInterpreterCommon/robotModel/twoD/parts/twoDDisplay.h>

using namespace trik;

TrikBrick::TrikBrick(const QSharedPointer<robotModel::twoD::TrikTwoDRobotModel> &model)
	: mTwoDRobotModel(model)
	, mDisplay(model)
	, mKeys(model)
	, mSensorUpdater(model->timeline().produceTimer())
{
	connect(this, &TrikBrick::log, this, &TrikBrick::printToShell);
	mSensorUpdater->setRepeatable(true);
	mSensorUpdater->setInterval(model->updateIntervalForInterpretation()); // seems to be x2 of timeline tick
	connect(mSensorUpdater.data(), &utils::AbstractTimer::timeout, [model](){
		model->updateSensorsValues(); /// @todo: maybe connect to model directly?
	});
}

TrikBrick::~TrikBrick()
{
	qDeleteAll(mMotors);
	qDeleteAll(mSensors);
	qDeleteAll(mEncoders);
	qDeleteAll(mLineSensors);
	qDeleteAll(mTimers);
}

void TrikBrick::reset()
{
	mKeys.reset();///@todo: reset motos/device maps?
	//mDisplay.reset(); - is actually needed? Crashes app at exit
	emit stopWaiting();
	for (const auto &m : mMotors) {
		m->powerOff();
	}
	for (const auto &e : mEncoders) {
		e->reset();
	}
	for (const auto &t : mTimers) {
		t->stop();
	}
	qDeleteAll(mTimers);
	mTimers.clear();
	QMetaObject::invokeMethod(mSensorUpdater.data(), "stop"); // failproof against timer manipulation in another thread
}

void TrikBrick::printToShell(const QString &msg)
{
	using namespace kitBase::robotModel;
	using namespace trik::robotModel;
	parts::TrikShell* sh = RobotModelUtils::findDevice<parts::TrikShell>(*mTwoDRobotModel, "ShellPort");
	if (sh == nullptr) {
		qDebug("Error: 2d model shell part was not found");
		return;
	}
	sh->print(msg);
}

void TrikBrick::init()
{
	mDisplay.init();
//	for (const auto &m : mMotors) {
//		m->powerOff();
//	}
//	for (const auto &e : mEncoders) {
//		e->read();
//	}
//	for (const auto &s : mSensors) {
//		s->read();
//	}
	mTwoDRobotModel->updateSensorsValues();
	mMotors.clear(); // needed? reset?
	mSensors.clear();
	mEncoders.clear();
	mKeys.init();
	mGyroscope.reset(); // for some reason it won't reconnect to the robot parts otherwise.
	QMetaObject::invokeMethod(mSensorUpdater.data(), "start"); // failproof against timer manipulation in another thread
	//mSensorUpdater.start();
}

void TrikBrick::setCurrentDir(const QString &dir)
{
	mCurrentDir = QFileInfo(dir).dir(); // maybe can be constructed directly
}

void TrikBrick::setCurrentInputs(const QString &f)
{
	mIsExcerciseMode = true;
	if (f.isEmpty()) {
		return; // no inputs has been passed, no need to complain
	}
	QString file(f);
	QFile in(file);
	if (!in.open(QIODevice::ReadOnly | QIODevice::Text)) {
		emit warning(tr("Trying to read from file %1 failed").arg(file)); // todo: remove? It's only in exercise.
		//not really an error, usually
	}

	QStringList result;

	while (!in.atEnd()) {
		const auto line = in.readLine();
		result << QString::fromUtf8(line);
	}

	mInputs = result;
}

void TrikBrick::say(const QString &msg) {
	using namespace kitBase::robotModel;
	using namespace trik::robotModel;
	parts::TrikShell* sh = RobotModelUtils::findDevice<parts::TrikShell>(*mTwoDRobotModel, "ShellPort");
	if (sh == nullptr) {
		qDebug("Error: 2d model shell part was not found");
		return;
	}
	QMetaObject::invokeMethod(sh, "say", Q_ARG(const QString &, msg));
}

void TrikBrick::stop() {
	/// @todo: properly implement this?
	mTwoDRobotModel->stopRobot();
//	for (const auto &m : mMotors) {
//		m->powerOff();
//	}
//	for (const auto &e : mEncoders) {
//		e->reset();
//	}
}

trikControl::MotorInterface *TrikBrick::motor(const QString &port)
{
	using namespace kitBase::robotModel;
	if (!mMotors.contains(port)) {
		robotParts::Motor * mot =
				RobotModelUtils::findDevice<robotParts::Motor>(*mTwoDRobotModel, port);
		if (mot == nullptr) {
			emit error(tr("No configured motor on port: %1").arg(port));
			return nullptr;
		}
		mMotors[port] = new TrikMotorEmu(mot);
	}
	return mMotors[port];
}

trikControl::MarkerInterface *TrikBrick::marker()
{
	kitBase::robotModel::PortInfo markerPort = kitBase::robotModel::RobotModelUtils::findPort(*mTwoDRobotModel
			, "MarkerPort"
			, kitBase::robotModel::Direction::output);
	if (markerPort.isValid()) {
		using Marker = twoDModel::robotModel::parts::Marker;
		Marker* marker = kitBase::robotModel::RobotModelUtils::findDevice<Marker>(*mTwoDRobotModel, markerPort);
		mTrikProxyMarker.reset(new TrikProxyMarker(marker));
		return mTrikProxyMarker.data();
	}

	return nullptr;
}

trikControl::SensorInterface *TrikBrick::sensor(const QString &port)
{
	//testing
	using namespace kitBase::robotModel;
	if (!mSensors.contains(port)) {
		robotParts::ScalarSensor * sens =
				RobotModelUtils::findDevice<robotParts::ScalarSensor>(*mTwoDRobotModel, port);
		if (sens == nullptr) {
			emit error(tr("No configured sensor on port: %1").arg(port));
			return nullptr;
		}
		mSensors[port] = new TrikSensorEmu(sens);
	}
	return mSensors[port];
}

QStringList TrikBrick::motorPorts(trikControl::MotorInterface::Type type) const
{
	Q_UNUSED(type)
//	QLOG_INFO() << "Motor type is ignored";
	return mMotors.keys();
}

QStringList TrikBrick::sensorPorts(trikControl::SensorInterface::Type type) const
{
	Q_UNUSED(type)
//	QLOG_INFO() << "Sensor type is ignored";
	return mMotors.keys();
}

QStringList TrikBrick::encoderPorts() const {
	return mEncoders.keys();
}

trikControl::VectorSensorInterface *TrikBrick::accelerometer() {
	using namespace kitBase::robotModel;
	if (mAccelerometer.isNull()) {
		auto a = RobotModelUtils::findDevice<robotParts::AccelerometerSensor>(*mTwoDRobotModel
				, "AccelerometerPort");
		if (a == nullptr) {
			emit error(tr("No configured accelerometer"));
			return nullptr;
		}
		mAccelerometer.reset(new TrikAccelerometerAdapter(a));
	}

	return mAccelerometer.data();
}

trikControl::GyroSensorInterface *TrikBrick::gyroscope() {
	using namespace kitBase::robotModel;
	if (mGyroscope.isNull()) {
		auto a = RobotModelUtils::findDevice<robotParts::GyroscopeSensor>(*mTwoDRobotModel
				, "GyroscopePort");
		if (a == nullptr) {
			emit error(tr("No configured gyroscope"));
			return nullptr;
		}
		mGyroscope.reset(new TrikGyroscopeAdapter(a, mTwoDRobotModel));
	}

	return mGyroscope.data();
}

trikControl::LineSensorInterface *TrikBrick::lineSensor(const QString &port) {
	using namespace trik::robotModel::parts;
	using namespace kitBase::robotModel;
	if (port == "video0") {
		return lineSensor("LineSensorPort"); // seems to be the case for 2d model
	}

	if (!mLineSensors.contains(port)) {
		TrikLineSensor * sens =
				RobotModelUtils::findDevice<TrikLineSensor>(*mTwoDRobotModel, port);
		if (sens == nullptr) {
			emit error(tr("No configured LineSensor on port: %1").arg(port));
			return nullptr;
		}
		mLineSensors[port] = new TrikLineSensorAdapter(sens);
	}

	return mLineSensors[port];
}

trikControl::EncoderInterface *TrikBrick::encoder(const QString &port) {
	using namespace kitBase::robotModel;
	if (!mEncoders.contains(port)) {
		robotParts::EncoderSensor * enc =
				RobotModelUtils::findDevice<robotParts::EncoderSensor>(*mTwoDRobotModel, port);
		if (enc == nullptr) {
			emit error(tr("No configured encoder on port: %1").arg(port));
			return nullptr;
		}

		mEncoders[port] = new TrikEncoderAdapter(enc->port(), mTwoDRobotModel->engine());
	}

	return mEncoders[port];
}

trikControl::DisplayInterface *TrikBrick::display()
{
//	trik::robotModel::parts::TrikDisplay * const display =
//			kitBase::robotModel::RobotModelUtils::findDevice<trik::robotModel::parts::TrikDisplay>(*mTwoDRobotModel
//					, "DisplayPort");
//	if (display) {
//		bool res = QMetaObject::invokeMethod(display,
//		"drawSmile",
//		Qt::QueuedConnection, // connection type, auto?
//		Q_ARG(bool, false));
//		//display->drawSmile(false);
//		printf(res ? "true" : "false");
//	}
//	return nullptr;
	return &mDisplay;
}

trikControl::LedInterface *TrikBrick::led() {
	using namespace trik::robotModel::parts;
	using namespace kitBase::robotModel;
	if (mLed.isNull()) {
		auto l = RobotModelUtils::findDevice<TrikLed>(*mTwoDRobotModel, "LedPort");
		if (l == nullptr) {
			emit error(tr("No configured led"));
			return nullptr;
		}
		mLed.reset(new TrikLedAdapter(l));
	}

	return mLed.data();
}

int TrikBrick::random(int from, int to)
{
	using namespace kitBase::robotModel;
	auto r = RobotModelUtils::findDevice<robotParts::Random>(*mTwoDRobotModel, "RandomPort");
	// maybe store it later, like the others
	if (!r) {
		emit error(tr("No cofigured random device"));
		return -1;
	}

	return r->random(from, to);
}

void TrikBrick::wait(int milliseconds)
{
	auto timeline = dynamic_cast<twoDModel::model::Timeline *> (&mTwoDRobotModel->timeline());

	if (timeline->isStarted()) {
		QSharedPointer<utils::AbstractTimer> t(timeline->produceTimer());
		QTimer abortTimer;
		QMetaObject::Connection abortConnection;
		QSharedPointer<QEventLoop> loop (new QEventLoop());

		auto mainHandler = [=]() {
			disconnect(abortConnection);
			disconnect(this, &TrikBrick::stopWaiting, nullptr, nullptr);
			disconnect(timeline, &twoDModel::model::Timeline::beforeStop, nullptr, nullptr);
			disconnect(t.data(), &utils::AbstractTimer::timeout, nullptr, nullptr);
			loop->quit();
		};

		auto abortHandler = [=]() {
			if (!timeline->isStarted()) {
				mainHandler();
			}
		};

		connect(t.data(), &utils::AbstractTimer::timeout, mainHandler);
		connect(this, &TrikBrick::stopWaiting, mainHandler);

		// timers that are produced by produceTimer() doesn't use stop singal
		// be careful, one who use just utils::AbstractTimer can stuck
		connect(timeline, &twoDModel::model::Timeline::beforeStop, mainHandler);
		abortConnection = connect(&abortTimer, &QTimer::timeout, abortHandler);

		// because timer is depends on twoDModel::model::Timeline
		if (timeline->isStarted()) {
			t->start(milliseconds);
			abortTimer.start(10);
			loop->exec();
		} else {
			mainHandler();
		}
	}
}

quint64 TrikBrick::time() const
{
	return mTwoDRobotModel->timeline().timestamp();
}

QStringList TrikBrick::readAll(const QString &path)
{
	if (mIsExcerciseMode) {
		return mInputs;
	}
	//if (mCurrentDir) todo: check that the current working dir is a save dir
	QFileInfo normalizedPath(mCurrentDir.absoluteFilePath(path)); // absoluteDir?
	QString file = normalizedPath.filePath();
	QFile in(file);
	if (!in.open(QIODevice::ReadOnly | QIODevice::Text)) {
		emit error(tr("Trying to read from file %1 failed").arg(file));
		return {};
	}

	QStringList result;

	while (!in.atEnd()) {
		const auto line = in.readLine();
		result << QString::fromUtf8(line);
	}

	return result;
}

utils::AbstractTimer *TrikBrick::timer(int milliseconds)
{
	utils::AbstractTimer *result = mTwoDRobotModel->timeline().produceTimer();
	mTimers.append(result);
	result->setRepeatable(true); // seems to be the case
	result->start(milliseconds);
	return result;
}

<|endoftext|>


<commit_before>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2004-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007      Inge Wallin  <ingwa@kde.org>
// Copyright 2008-2009      Patrick Spendrin <ps_ml@gmx.de>
//

// Own
#include "GeoDataPlacemark.h"

// Private
#include "GeoDataPlacemark_p.h"

// Qt
#include <QtCore/QDataStream>
#include <QtCore/QDebug>

namespace Marble
{
GeoDataPlacemark::GeoDataPlacemark()
    : GeoDataFeature( new GeoDataPlacemarkPrivate )
{
}

GeoDataPlacemark::GeoDataPlacemark( const GeoDataPlacemark& other )
: GeoDataFeature( other )
{
}

GeoDataPlacemark::GeoDataPlacemark( const GeoDataFeature& other )
: GeoDataFeature( other )
{
}

GeoDataPlacemark::GeoDataPlacemark( const QString& name )
    : GeoDataFeature( name )
{
}

GeoDataPlacemark::~GeoDataPlacemark()
{
}

bool GeoDataPlacemark::operator==( const GeoDataPlacemark& other ) const
{
    return p() == other.p();
}

GeoDataPlacemarkPrivate* GeoDataPlacemark::p() const
{
    return static_cast<GeoDataPlacemarkPrivate*>(d);
}

GeoDataGeometry* GeoDataPlacemark::geometry() const
{
    if( p()->m_geometry )
        return p()->m_geometry;
    else
        return &( p()->m_coordinate );
}

GeoDataCoordinates GeoDataPlacemark::coordinate() const
{
    return static_cast<GeoDataCoordinates>( p()->m_coordinate );
}

void GeoDataPlacemark::coordinate( qreal& lon, qreal& lat, qreal& alt ) const
{
    p()->m_coordinate.geoCoordinates( lon, lat );
    alt = p()->m_coordinate.altitude();
}

void GeoDataPlacemark::setCoordinate( qreal lon, qreal lat, qreal alt )
{
    detach();
    p()->m_coordinate = GeoDataPoint( lon, lat, alt );
}

void GeoDataPlacemark::setCoordinate( const GeoDataPoint &point )
{
    detach();
    p()->m_coordinate = GeoDataPoint( point );
}

void GeoDataPlacemark::setGeometry( const GeoDataPoint& point )
{
    detach();
    p()->m_geometry = new GeoDataPoint( point );
}

void GeoDataPlacemark::setGeometry( const GeoDataLineString& point )
{
    detach();
    p()->m_geometry = new GeoDataLineString( point );
}

void GeoDataPlacemark::setGeometry( const GeoDataLinearRing& point )
{
    detach();
    p()->m_geometry = new GeoDataLinearRing( point );
}

void GeoDataPlacemark::setGeometry( const GeoDataPolygon& point )
{
    detach();
    p()->m_geometry = new GeoDataPolygon( point );
}

void GeoDataPlacemark::setGeometry( const GeoDataMultiGeometry& point )
{
    detach();
    p()->m_geometry = new GeoDataMultiGeometry( point );
}

qreal GeoDataPlacemark::area() const
{
    return p()->m_area;
}

void GeoDataPlacemark::setArea( qreal area )
{
    detach();
    p()->m_area = area;
}

qint64 GeoDataPlacemark::population() const
{
    return p()->m_population;
}

void GeoDataPlacemark::setPopulation( qint64 population )
{
    detach();
    p()->m_population = population;
}

const QString GeoDataPlacemark::countryCode() const
{
    return p()->m_countrycode;
}

void GeoDataPlacemark::setCountryCode( const QString &countrycode )
{
    detach();
    p()->m_countrycode = countrycode;
}

void GeoDataPlacemark::pack( QDataStream& stream ) const
{
    GeoDataFeature::pack( stream );

    stream << p()->m_countrycode;
    stream << p()->m_area;
    stream << p()->m_population;

    stream << p()->m_geometry->geometryId();
    p()->m_geometry->pack( stream );
    p()->m_coordinate.pack( stream );
}

void GeoDataPlacemark::unpack( QDataStream& stream )
{
    detach();
    GeoDataFeature::unpack( stream );

    stream >> p()->m_countrycode;
    stream >> p()->m_area;
    stream >> p()->m_population;

    int geometryId;
    stream >> geometryId;
    switch( geometryId ) {
        case InvalidGeometryId:
            break;
        case GeoDataPointId:
            {
            GeoDataPoint* point = new GeoDataPoint;
            point->unpack( stream );
            delete p()->m_geometry;
            p()->m_geometry = point;
            }
            break;
        case GeoDataLineStringId:
            {
            GeoDataLineString* lineString = new GeoDataLineString;
            lineString->unpack( stream );
            delete p()->m_geometry;
            p()->m_geometry = lineString;
            }
            break;
        case GeoDataLinearRingId:
            {
            GeoDataLinearRing* linearRing = new GeoDataLinearRing;
            linearRing->unpack( stream );
            delete p()->m_geometry;
            p()->m_geometry = linearRing;
            }
            break;
        case GeoDataPolygonId:
            {
            GeoDataPolygon* polygon = new GeoDataPolygon;
            polygon->unpack( stream );
            delete p()->m_geometry;
            p()->m_geometry = polygon;
            }
            break;
        case GeoDataMultiGeometryId:
            {
            GeoDataMultiGeometry* multiGeometry = new GeoDataMultiGeometry;
            multiGeometry->unpack( stream );
            delete p()->m_geometry;
            p()->m_geometry = multiGeometry;
            }
            break;
        case GeoDataModelId:
            break;
        default: break;
    };
    p()->m_coordinate.unpack( stream );
}

}
<commit_msg>delete the geometry also when resetting it<commit_after>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2004-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007      Inge Wallin  <ingwa@kde.org>
// Copyright 2008-2009      Patrick Spendrin <ps_ml@gmx.de>
//

// Own
#include "GeoDataPlacemark.h"

// Private
#include "GeoDataPlacemark_p.h"

// Qt
#include <QtCore/QDataStream>
#include <QtCore/QDebug>

namespace Marble
{
GeoDataPlacemark::GeoDataPlacemark()
    : GeoDataFeature( new GeoDataPlacemarkPrivate )
{
}

GeoDataPlacemark::GeoDataPlacemark( const GeoDataPlacemark& other )
: GeoDataFeature( other )
{
}

GeoDataPlacemark::GeoDataPlacemark( const GeoDataFeature& other )
: GeoDataFeature( other )
{
}

GeoDataPlacemark::GeoDataPlacemark( const QString& name )
    : GeoDataFeature( name )
{
}

GeoDataPlacemark::~GeoDataPlacemark()
{
}

bool GeoDataPlacemark::operator==( const GeoDataPlacemark& other ) const
{
    return p() == other.p();
}

GeoDataPlacemarkPrivate* GeoDataPlacemark::p() const
{
    return static_cast<GeoDataPlacemarkPrivate*>(d);
}

GeoDataGeometry* GeoDataPlacemark::geometry() const
{
    if( p()->m_geometry )
        return p()->m_geometry;
    else
        return &( p()->m_coordinate );
}

GeoDataCoordinates GeoDataPlacemark::coordinate() const
{
    return static_cast<GeoDataCoordinates>( p()->m_coordinate );
}

void GeoDataPlacemark::coordinate( qreal& lon, qreal& lat, qreal& alt ) const
{
    p()->m_coordinate.geoCoordinates( lon, lat );
    alt = p()->m_coordinate.altitude();
}

void GeoDataPlacemark::setCoordinate( qreal lon, qreal lat, qreal alt )
{
    detach();
    p()->m_coordinate = GeoDataPoint( lon, lat, alt );
}

void GeoDataPlacemark::setCoordinate( const GeoDataPoint &point )
{
    detach();
    p()->m_coordinate = GeoDataPoint( point );
}

void GeoDataPlacemark::setGeometry( const GeoDataPoint& point )
{
    detach();
    delete p()->m_geometry;
    p()->m_geometry = new GeoDataPoint( point );
}

void GeoDataPlacemark::setGeometry( const GeoDataLineString& point )
{
    detach();
    delete p()->m_geometry;
    p()->m_geometry = new GeoDataLineString( point );
}

void GeoDataPlacemark::setGeometry( const GeoDataLinearRing& point )
{
    detach();
    delete p()->m_geometry;
    p()->m_geometry = new GeoDataLinearRing( point );
}

void GeoDataPlacemark::setGeometry( const GeoDataPolygon& point )
{
    detach();
    delete p()->m_geometry;
    p()->m_geometry = new GeoDataPolygon( point );
}

void GeoDataPlacemark::setGeometry( const GeoDataMultiGeometry& point )
{
    detach();
    delete p()->m_geometry;
    p()->m_geometry = new GeoDataMultiGeometry( point );
}

qreal GeoDataPlacemark::area() const
{
    return p()->m_area;
}

void GeoDataPlacemark::setArea( qreal area )
{
    detach();
    p()->m_area = area;
}

qint64 GeoDataPlacemark::population() const
{
    return p()->m_population;
}

void GeoDataPlacemark::setPopulation( qint64 population )
{
    detach();
    p()->m_population = population;
}

const QString GeoDataPlacemark::countryCode() const
{
    return p()->m_countrycode;
}

void GeoDataPlacemark::setCountryCode( const QString &countrycode )
{
    detach();
    p()->m_countrycode = countrycode;
}

void GeoDataPlacemark::pack( QDataStream& stream ) const
{
    GeoDataFeature::pack( stream );

    stream << p()->m_countrycode;
    stream << p()->m_area;
    stream << p()->m_population;

    stream << p()->m_geometry->geometryId();
    p()->m_geometry->pack( stream );
    p()->m_coordinate.pack( stream );
}

void GeoDataPlacemark::unpack( QDataStream& stream )
{
    detach();
    GeoDataFeature::unpack( stream );

    stream >> p()->m_countrycode;
    stream >> p()->m_area;
    stream >> p()->m_population;

    int geometryId;
    stream >> geometryId;
    switch( geometryId ) {
        case InvalidGeometryId:
            break;
        case GeoDataPointId:
            {
            GeoDataPoint* point = new GeoDataPoint;
            point->unpack( stream );
            delete p()->m_geometry;
            p()->m_geometry = point;
            }
            break;
        case GeoDataLineStringId:
            {
            GeoDataLineString* lineString = new GeoDataLineString;
            lineString->unpack( stream );
            delete p()->m_geometry;
            p()->m_geometry = lineString;
            }
            break;
        case GeoDataLinearRingId:
            {
            GeoDataLinearRing* linearRing = new GeoDataLinearRing;
            linearRing->unpack( stream );
            delete p()->m_geometry;
            p()->m_geometry = linearRing;
            }
            break;
        case GeoDataPolygonId:
            {
            GeoDataPolygon* polygon = new GeoDataPolygon;
            polygon->unpack( stream );
            delete p()->m_geometry;
            p()->m_geometry = polygon;
            }
            break;
        case GeoDataMultiGeometryId:
            {
            GeoDataMultiGeometry* multiGeometry = new GeoDataMultiGeometry;
            multiGeometry->unpack( stream );
            delete p()->m_geometry;
            p()->m_geometry = multiGeometry;
            }
            break;
        case GeoDataModelId:
            break;
        default: break;
    };
    p()->m_coordinate.unpack( stream );
}

}
<|endoftext|>


<commit_before>// Copyright (c) 2012 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/browser/idle.h"

#include "base/basictypes.h"

#if defined(USE_X11)
#include "chrome/browser/idle_query_x11.h"
#endif

#if !defined(OS_CHROMEOS)
#include "chrome/browser/screensaver_window_finder_x11.h"
#endif

void CalculateIdleTime(IdleTimeCallback notify) {
#if defined(USE_X11)
  chrome::IdleQueryX11 idle_query;
  notify.Run(idle_query.IdleTime());
#endif
}

bool CheckIdleStateIsLocked() {
  // Usually the screensaver is used to lock the screen, so we do not need to
  // check if the workstation is locked.
#if defined(OS_CHROMEOS)
  return false;
#else
  return ScreensaverWindowFinder::ScreensaverWindowExists();
#endif
}
<commit_msg>chrome: Check idle state for Ozone platform<commit_after>// Copyright (c) 2012 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/browser/idle.h"

#include "base/basictypes.h"

#if defined(USE_X11)
#include "chrome/browser/idle_query_x11.h"
#endif

#if !defined(OS_CHROMEOS)
#include "chrome/browser/screensaver_window_finder_x11.h"
#endif

void CalculateIdleTime(IdleTimeCallback notify) {
#if defined(USE_X11)
  chrome::IdleQueryX11 idle_query;
  notify.Run(idle_query.IdleTime());
#endif
}

bool CheckIdleStateIsLocked() {
  // Usually the screensaver is used to lock the screen, so we do not need to
  // check if the workstation is locked.
#if defined(OS_CHROMEOS)
  return false;
#elif defined(USE_OZONE)
  return false;
#else
  return ScreensaverWindowFinder::ScreensaverWindowExists();
#endif
}
<|endoftext|>


<commit_before>/** \file Ex7.cpp
 *  \brief This example shows how to set and solve the weak form
 *   of the Boussinesq appoximation of the Navier-Stokes Equation
 *
 *  \f{eqnarray*}
 *  && \mathbf{V} \cdot \nabla T - \nabla \cdot\alpha \nabla T = 0 \\
 *  && \mathbf{V} \cdot \nabla \mathbf{V} - \nabla \cdot \nu (\nabla \mathbf{V} +(\nabla \mathbf{V})^T)
 *  +\nabla P = \beta T \mathbf{j} \\
 *  && \nabla \cdot \mathbf{V} = 0
 *  \f}
 *  in a unit box domain (in 2D and 3D) with given temperature 0 and 1 on
 *  the left and right walls, respectively, and insulated walls elsewhere.
 *  \author Eugenio Aulisa
 */

#include "FemusInit.hpp"
#include "MultiLevelProblem.hpp"
#include "NumericVector.hpp"
#include "VTKWriter.hpp"
#include "GMVWriter.hpp"
#include "NonLinearImplicitSystem.hpp"
#include "adept.h"

using namespace femus;

bool SetBoundaryCondition(const std::vector < double >& x, const char SolName[], double& value, const int facename, const double time) {
  bool dirichlet = true; //dirichlet
  value = 0.;
  return dirichlet;
}

bool SetRefinementFlag(const std::vector < double >& x, const int& elemgroupnumber, const int& level) {

  bool refine = 0;

  if (elemgroupnumber == 6 && level < 4) refine = 1;

  if (elemgroupnumber == 7 && level < 5) refine = 1;

  if (elemgroupnumber == 8 && level < 6) refine = 1;

//   if (elemgroupnumber==6 && level<1) refine=1;
//   if (elemgroupnumber==7 && level<2) refine=1;
//   if (elemgroupnumber==8 && level<3) refine=1;

  return refine;

}

void AssemblePoisson_AD(MultiLevelProblem& ml_prob);    //, unsigned level, const unsigned &levelMax, const bool &assembleMatrix );

int main(int argc, char** args) {

  // init Petsc-MPI communicator
  FemusInit mpinit(argc, args, MPI_COMM_WORLD);

  // define multilevel mesh
  MultiLevelMesh mlMsh;
  // read coarse level mesh and generate finers level meshes
  double scalingFactor = 1.;
  //mlMsh.ReadCoarseMesh("./input/cube_hex.neu","seventh",scalingFactor);
  //mlMsh.ReadCoarseMesh("./input/square_quad.neu", "seventh", scalingFactor);
  mlMsh.ReadCoarseMesh("./input/quadAMR.neu", "seventh", scalingFactor);
  /* "seventh" is the order of accuracy that is used in the gauss integration scheme
     probably in the furure it is not going to be an argument of this function   */
  unsigned dim = mlMsh.GetDimension();

//   unsigned numberOfUniformLevels = 3;
//   unsigned numberOfSelectiveLevels = 0;
//   mlMsh.RefineMesh(numberOfUniformLevels , numberOfUniformLevels + numberOfSelectiveLevels, NULL);

  unsigned numberOfUniformLevels = 4;
  unsigned numberOfSelectiveLevels = 3;
  mlMsh.RefineMesh(numberOfUniformLevels + numberOfSelectiveLevels, numberOfUniformLevels , SetRefinementFlag);

  // erase all the coarse mesh levels
  //mlMsh.EraseCoarseLevels(numberOfUniformLevels - 3);

  // print mesh info
  mlMsh.PrintInfo();

  MultiLevelSolution mlSol(&mlMsh);

  // add variables to mlSol

  mlSol.AddSolution("V", LAGRANGE, SECOND);

  mlSol.AddSolution("U", LAGRANGE, SECOND);

  mlSol.Initialize("All");

  // attach the boundary condition function and generate boundary data
  mlSol.AttachSetBoundaryConditionFunction(SetBoundaryCondition);

  mlSol.GenerateBdc("All");

  // define the multilevel problem attach the mlSol object to it
  MultiLevelProblem mlProb(&mlSol);

  // add system Poisson in mlProb as a Linear Implicit System
  NonLinearImplicitSystem& system = mlProb.add_system < NonLinearImplicitSystem > ("Poisson");

  // add solution "u" to system
  system.AddSolutionToSystemPDE("U");

  //system.SetMgSmoother(GMRES_SMOOTHER);
  system.SetMgSmoother(ASM_SMOOTHER); // Additive Swartz Method
  // attach the assembling function to system
  system.SetAssembleFunction(AssemblePoisson_AD);

  system.SetMaxNumberOfNonLinearIterations(10);
  system.SetMaxNumberOfLinearIterations(3);
  system.SetLinearConvergenceTolerance(1.e-12);
  system.SetNonLinearConvergenceTolerance(1.e-8);
  system.SetMgType(F_CYCLE); // Q1 What's F cycle

  system.SetNumberPreSmoothingStep(0);  // Q2 What's Pre (post) smoothing step? Is related to smoothstep?
  system.SetNumberPostSmoothingStep(2);
  // initilaize and solve the system
  system.init();

  system.SetSolverFineGrids(GMRES);
  system.SetPreconditionerFineGrids(ILU_PRECOND);
  system.SetTolerances(1.e-3, 1.e-20, 1.e+50, 5);

  system.SetNumberOfSchurVariables(1);
  system.SetElementBlockNumber(4);
  //system.SetDirichletBCsHandling(ELIMINATION); // Q3 What's BCsHandling?
  //system.solve();
  system.MGsolve();

  // print solutions
  std::vector < std::string > variablesToBePrinted;
  variablesToBePrinted.push_back("All");

  VTKWriter vtkIO(&mlSol);
  vtkIO.write(DEFAULT_OUTPUTDIR, "biquadratic", variablesToBePrinted);

  GMVWriter gmvIO(&mlSol);
  variablesToBePrinted.push_back("all");
  gmvIO.SetDebugOutput(true);
  gmvIO.write(DEFAULT_OUTPUTDIR, "biquadratic", variablesToBePrinted);

  return 0;
}

void AssemblePoisson_AD(MultiLevelProblem& ml_prob) {
  //  ml_prob is the global object from/to where get/set all the data
  //  level is the level of the PDE system to be assembled
  //  levelMax is the Maximum level of the MultiLevelProblem
  //  assembleMatrix is a flag that tells if only the residual or also the matrix should be assembled

  // call the adept stack object
  adept::Stack& s = FemusInit::_adeptStack;

  //  extract pointers to the several objects that we are going to use
  NonLinearImplicitSystem* mlPdeSys   = &ml_prob.get_system<NonLinearImplicitSystem> ("Poisson");   // pointer to the linear implicit system named "Poisson"
  const unsigned level = mlPdeSys->GetLevelToAssemble();

  Mesh*           msh         = ml_prob._ml_msh->GetLevel(level);    // pointer to the mesh (level) object
  elem*           el          = msh->el;  // pointer to the elem object in msh (level)

  MultiLevelSolution*   mlSol = ml_prob._ml_sol;  // pointer to the multilevel solution object
  Solution*   sol             = ml_prob._ml_sol->GetSolutionLevel(level);    // pointer to the solution (level) object

  LinearEquationSolver* pdeSys  = mlPdeSys->_LinSolver[level];  // pointer to the equation (level) object
  SparseMatrix*   KK          = pdeSys->_KK;  // pointer to the global stifness matrix object in pdeSys (level)
  NumericVector*  RES         = pdeSys->_RES; // pointer to the global residual vector object in pdeSys (level)

  const unsigned  dim = msh->GetDimension(); // get the domain dimension of the problem
  unsigned dim2 = (3 * (dim - 1) + !(dim - 1));        // dim2 is the number of second order partial derivatives (1,3,6 depending on the dimension)// Q4 How to get the equation?
  unsigned    iproc = msh->processor_id(); // get the process_id (for parallel computation)

  // reserve memory for the local standar vectors
  const unsigned maxSize = static_cast< unsigned >(ceil(pow(3, dim)));          // conservative: based on line3, quad9, hex27

  //solution variable
  unsigned solUIndex;
  solUIndex = mlSol->GetIndex("U");    // get the position of "U" in the ml_sol object = 0
  unsigned solUType = mlSol->GetSolutionType(solUIndex);    // get the finite element type for "T"

  unsigned solUPdeIndex;
  solUPdeIndex = mlPdeSys->GetSolPdeIndex("U");    // get the position of "U" in the pdeSys object = 0

  std::cout << solUIndex << " " << solUPdeIndex << std::endl;

  vector < adept::adouble >  solU; // local solution
  vector< adept::adouble > aResU; // local redidual vector

  vector < vector < double > > crdX(dim);    // local coordinates
  unsigned crdXType = 2; // get the finite element type for "x", it is always 2 (LAGRANGE QUADRATIC)

  solU.reserve(maxSize);
  aResU.reserve(maxSize);

  for (unsigned  k = 0; k < dim; k++) {
    crdX[k].reserve(maxSize);
  }

  vector <double> phi;  // local test function
  vector <double> phi_x; // local test function first order partial derivatives
  vector <double> phi_xx; // local test function second order partial derivatives

  phi.reserve(maxSize);
  phi_x.reserve(maxSize * dim);
  phi_xx.reserve(maxSize * dim2);

  double weight; // gauss point weight

  vector< int > sysDof; // local to global pdeSys dofs
  sysDof.reserve(maxSize);

  vector< double > ResU; // local residual vector
  ResU.reserve(maxSize);

  vector < double > Jac;
  Jac.reserve(maxSize * maxSize);

  KK->zero(); // Set to zero all the entries of the Global Matrix

  // element loop: each process loops only on the elements that owns // Q5 What's the loop mean(mapping between parallel dof and mesh dof)?
  for (int iel = msh->_elementOffset[iproc]; iel < msh->_elementOffset[iproc + 1]; iel++) {

    short unsigned ielGeom = msh->GetElementType(iel);      // element geometry type

    unsigned nDofsU = msh->GetElementDofNumber(iel, solUType);      // number of solution element dofs
    unsigned nDofsX = msh->GetElementDofNumber(iel, crdXType);      // number of solution element dofs

    // resize local arrays
    sysDof.resize(nDofsU);
    solU.resize(nDofsU);

    for (unsigned  k = 0; k < dim; k++) {
      crdX[k].resize(nDofsX);
    }

    aResU.assign(nDofsU, 0);

    // local storage of global mapping and solution
    for (unsigned i = 0; i < nDofsU; i++) {
      unsigned solUDof = msh->GetSolutionDof(i, iel, solUType);    // local to global mapping of the solution U
      solU[i] = (*sol->_Sol[solUIndex])(solUDof);      // value of the solution U in the dofs
      sysDof[i] = pdeSys->GetSystemDof(solUIndex, solUPdeIndex, i, iel);    // local to global mapping between solution U and system
    }

    // local storage of coordinates
    for (unsigned i = 0; i < nDofsX; i++) {
      unsigned coordXDof  = msh->GetSolutionDof(i, iel, crdXType);   // local to global mapping of the coordinate X[dim]

      for (unsigned k = 0; k < dim; k++) {
        crdX[k][i] = (*msh->_topology->_Sol[k])(coordXDof);      // value of the solution X[dim]  // Q6 Why does msh pointer to topology?
      }
    }

    s.new_recording();

    // *** Gauss point loop *** //
    for (unsigned ig = 0; ig < msh->_finiteElement[ielGeom][solUType]->GetGaussPointNumber(); ig++) {
      // *** get gauss point weight, test function and test function partial derivatives ***
      msh->_finiteElement[ielGeom][solUType]->Jacobian(crdX, ig, weight, phi, phi_x, phi_xx);

      adept::adouble solUig = 0; // solution U in the gauss point
      vector < adept::adouble > gradSolUig(dim, 0.); // gradient of solution U in the gauss point

      for (unsigned i = 0; i < nDofsU; i++) {
        solUig += phi[i] * solU[i];

        for (unsigned j = 0; j < dim; j++) {
          gradSolUig[j] += phi_x[i * dim + j] * solU[i]; // Q7 [i * dim + j]?
        }
      }

      double nu = 1.;

      // *** phiU_i loop ***
      for (unsigned i = 0; i < nDofsU; i++) {
        adept::adouble LaplaceU = 0.;

        for (unsigned j = 0; j < dim; j++) {
          LaplaceU +=  nu * phi_x[i * dim + j] * gradSolUig[j];
        }

        aResU[i] += (phi[i] - LaplaceU) * weight;

      } // end phiU_i loop
    } // end gauss point loop

    // } // endif single element not refined or fine grid loop

    //--------------------------------------------------------------------------------------------------------
    // Add the local Matrix/Vector into the global Matrix/Vector

    //copy the value of the adept::adoube aRes in double Res and store them in RES
    ResU.resize(nDofsU);    //resize

    for (int i = 0; i < nDofsU; i++) {
      ResU[i] = -aResU[i].value();
    }

    RES->add_vector_blocked(ResU, sysDof);

    //Extarct and store the Jacobian

    Jac.resize(nDofsU * nDofsU);
    // define the dependent variables
    s.dependent(&aResU[0], nDofsU);

    // define the independent variables
    s.independent(&solU[0], nDofsU);

    // get the and store jacobian matrix (row-major)
    s.jacobian(&Jac[0] , true);
    KK->add_matrix_blocked(Jac, sysDof, sysDof);

    s.clear_independents();
    s.clear_dependents();

  } //end element loop for each process

  RES->close();

  KK->close();

  // ***************** END ASSEMBLY *******************
}

<commit_msg>building AMR_ex2, incomplete.<commit_after>/** \file Ex7.cpp
 *  \brief This example shows how to set and solve the weak form
 *   of the Boussinesq appoximation of the Navier-Stokes Equation
 *
 *  \f{eqnarray*}
 *  && \mathbf{V} \cdot \nabla T - \nabla \cdot\alpha \nabla T = 0 \\
 *  && \mathbf{V} \cdot \nabla \mathbf{V} - \nabla \cdot \nu (\nabla \mathbf{V} +(\nabla \mathbf{V})^T)
 *  +\nabla P = \beta T \mathbf{j} \\
 *  && \nabla \cdot \mathbf{V} = 0
 *  \f}
 *  in a unit box domain (in 2D and 3D) with given temperature 0 and 1 on
 *  the left and right walls, respectively, and insulated walls elsewhere.
 *  \author Eugenio Aulisa
 */
/** AMR_ex2
 * Solve
 * \nabla u = 1\\
 * \nabla v = u\\
 *        u = 0 on boundary\\
 *        v = 1 on boundary
 */

#include "FemusInit.hpp"
#include "MultiLevelProblem.hpp"
#include "NumericVector.hpp"
#include "VTKWriter.hpp"
#include "GMVWriter.hpp"
#include "NonLinearImplicitSystem.hpp"
#include "adept.h"

using namespace femus;

bool SetBoundaryCondition(const std::vector < double >& x, const char SolName[], double& value, const int facename, const double time) {
  bool dirichlet = true; //dirichlet
  if (!strcmp(SolName, "U")) {
    value = 0.;
  } else if (!strcmp(SolName, "V")) {
    value = 1.;

  }
  return dirichlet;
}

bool SetRefinementFlag(const std::vector < double >& x, const int& elemgroupnumber, const int& level) {

  bool refine = 0;

  if (elemgroupnumber == 6 && level < 4) refine = 1;

  if (elemgroupnumber == 7 && level < 5) refine = 1;

  if (elemgroupnumber == 8 && level < 6) refine = 1;

//   if (elemgroupnumber==6 && level<1) refine=1;
//   if (elemgroupnumber==7 && level<2) refine=1;
//   if (elemgroupnumber==8 && level<3) refine=1;

  return refine;

}

void AssemblePoisson_AD(MultiLevelProblem& ml_prob);    //, unsigned level, const unsigned &levelMax, const bool &assembleMatrix );

int main(int argc, char** args) {

  // init Petsc-MPI communicator
  FemusInit mpinit(argc, args, MPI_COMM_WORLD);

  // define multilevel mesh
  MultiLevelMesh mlMsh;
  // read coarse level mesh and generate finers level meshes
  double scalingFactor = 1.;
  //mlMsh.ReadCoarseMesh("./input/cube_hex.neu","seventh",scalingFactor);
  //mlMsh.ReadCoarseMesh("./input/square_quad.neu", "seventh", scalingFactor);
  mlMsh.ReadCoarseMesh("./input/quadAMR.neu", "seventh", scalingFactor);
  /* "seventh" is the order of accuracy that is used in the gauss integration scheme
     probably in the furure it is not going to be an argument of this function   */
  unsigned dim = mlMsh.GetDimension();

//   unsigned numberOfUniformLevels = 3;
//   unsigned numberOfSelectiveLevels = 0;
//   mlMsh.RefineMesh(numberOfUniformLevels , numberOfUniformLevels + numberOfSelectiveLevels, NULL);

  unsigned numberOfUniformLevels = 4;
  unsigned numberOfSelectiveLevels = 3;
  mlMsh.RefineMesh(numberOfUniformLevels + numberOfSelectiveLevels, numberOfUniformLevels , SetRefinementFlag);

  // erase all the coarse mesh levels
  //mlMsh.EraseCoarseLevels(numberOfUniformLevels - 3);

  // print mesh info
  mlMsh.PrintInfo();

  MultiLevelSolution mlSol(&mlMsh);

  // add variables to mlSol

  mlSol.AddSolution("V", LAGRANGE, SECOND);

  mlSol.AddSolution("U", LAGRANGE, FIRST);

  mlSol.Initialize("All");

  // attach the boundary condition function and generate boundary data
  mlSol.AttachSetBoundaryConditionFunction(SetBoundaryCondition);

  mlSol.GenerateBdc("All");

  // define the multilevel problem attach the mlSol object to it
  MultiLevelProblem mlProb(&mlSol);

  // add system Poisson in mlProb as a Linear Implicit System
  NonLinearImplicitSystem& system = mlProb.add_system < NonLinearImplicitSystem > ("Poisson");

  // add solution "u" to system
  system.AddSolutionToSystemPDE("U");
  system.AddSolutionToSystemPDE("V");

  //system.SetMgSmoother(GMRES_SMOOTHER);
  system.SetMgSmoother(ASM_SMOOTHER); // Additive Swartz Method
  // attach the assembling function to system
  system.SetAssembleFunction(AssemblePoisson_AD);

  system.SetMaxNumberOfNonLinearIterations(10);
  system.SetMaxNumberOfLinearIterations(3);
  system.SetLinearConvergenceTolerance(1.e-12);
  system.SetNonLinearConvergenceTolerance(1.e-8);
  system.SetMgType(F_CYCLE);

  system.SetNumberPreSmoothingStep(0);
  system.SetNumberPostSmoothingStep(2);
  // initilaize and solve the system
  system.init();

  system.SetSolverFineGrids(GMRES);
  system.SetPreconditionerFineGrids(ILU_PRECOND);
  system.SetTolerances(1.e-3, 1.e-20, 1.e+50, 5);

  system.SetNumberOfSchurVariables(1);
  system.SetElementBlockNumber(4);
  //system.SetDirichletBCsHandling(ELIMINATION);
  //system.solve();
  system.MGsolve();

  // print solutions
  std::vector < std::string > variablesToBePrinted;
  variablesToBePrinted.push_back("All");

  VTKWriter vtkIO(&mlSol);
  vtkIO.write(DEFAULT_OUTPUTDIR, "biquadratic", variablesToBePrinted);

  GMVWriter gmvIO(&mlSol);
  variablesToBePrinted.push_back("all");
  gmvIO.SetDebugOutput(true);
  gmvIO.write(DEFAULT_OUTPUTDIR, "biquadratic", variablesToBePrinted);

  return 0;
}

void AssemblePoisson_AD(MultiLevelProblem& ml_prob) {
  //  ml_prob is the global object from/to where get/set all the data
  //  level is the level of the PDE system to be assembled
  //  levelMax is the Maximum level of the MultiLevelProblem
  //  assembleMatrix is a flag that tells if only the residual or also the matrix should be assembled

  // call the adept stack object
  adept::Stack& s = FemusInit::_adeptStack;

  //  extract pointers to the several objects that we are going to use
  NonLinearImplicitSystem* mlPdeSys   = &ml_prob.get_system<NonLinearImplicitSystem> ("Poisson");   // pointer to the linear implicit system named "Poisson"
  const unsigned level = mlPdeSys->GetLevelToAssemble();

  Mesh*           msh         = ml_prob._ml_msh->GetLevel(level);    // pointer to the mesh (level) object
  elem*           el          = msh->el;  // pointer to the elem object in msh (level)

  MultiLevelSolution*   mlSol = ml_prob._ml_sol;  // pointer to the multilevel solution object
  Solution*   sol             = ml_prob._ml_sol->GetSolutionLevel(level);    // pointer to the solution (level) object

  LinearEquationSolver* pdeSys  = mlPdeSys->_LinSolver[level];  // pointer to the equation (level) object
  SparseMatrix*   KK          = pdeSys->_KK;  // pointer to the global stifness matrix object in pdeSys (level)
  NumericVector*  RES         = pdeSys->_RES; // pointer to the global residual vector object in pdeSys (level)

  const unsigned  dim = msh->GetDimension(); // get the domain dimension of the problem
  unsigned dim2 = (3 * (dim - 1) + !(dim - 1));        // dim2 is the number of second order partial derivatives (1,3,6 depending on the dimension)
  unsigned    iproc = msh->processor_id(); // get the process_id (for parallel computation)

  // reserve memory for the local standar vectors
  const unsigned maxSize = static_cast< unsigned >(ceil(pow(3, dim)));          // conservative: based on line3, quad9, hex27

  //solution variable
  unsigned solUIndex;
  solUIndex = mlSol->GetIndex("U");    // get the position of "U" in the ml_sol object = 0
  unsigned solUType = mlSol->GetSolutionType(solUIndex);    // get the finite element type for "T"

  unsigned solUPdeIndex;
  solUPdeIndex = mlPdeSys->GetSolPdeIndex("U");    // get the position of "U" in the pdeSys object = 0

  std::cout << solUIndex << " " << solUPdeIndex << std::endl;

  vector < adept::adouble >  solU; // local solution
  vector< adept::adouble > aResU; // local redidual vector

  unsigned solVIndex;
  solVIndex = mlSol->GetIndex("V");
  unsigned solVType = mlSol->GetSolutionType(solVIndex);

  unsigned solVPdeIndex;
  solVPdeIndex = mlPdeSys->GetSolPdeIndex("V");

  std::cout << solVIndex << " " << solVPdeIndex << std::endl;

  vector < adept::adouble >  solV; // local solution
  vector< adept::adouble > aResV; // local redidual vector

  vector < vector < double > > crdX(dim);    // local coordinates
  unsigned crdXType = 2; // get the finite element type for "x", it is always 2 (LAGRANGE QUADRATIC)

  solU.reserve(maxSize);
  aResU.reserve(maxSize);

  solV.reserve(maxSize);
  aResV.reserve(maxSize);

  for (unsigned  k = 0; k < dim; k++) {
    crdX[k].reserve(maxSize);
  }

  vector <double> phi;  // local test function
  vector <double> phi_x; // local test function first order partial derivatives
  vector <double> phi_xx; // local test function second order partial derivatives

  phi.reserve(maxSize);
  phi_x.reserve(maxSize * dim);
  phi_xx.reserve(maxSize * dim2);

  vector <double> phiV;  // local test function
  vector <double> phiV_x; // local test function first order partial derivatives
  vector <double> phiV_xx; // local test function second order partial derivatives

  phiV.reserve(maxSize);
  phiV_x.reserve(maxSize * dim);
  phiV_xx.reserve(maxSize * dim2);

  double weight; // gauss point weight

  vector< int > sysDof; // local to global pdeSys dofs
  sysDof.reserve(maxSize);

  vector< double > Res; // local residual vector
  Res.reserve(maxSize);

  vector < double > Jac;
  Jac.reserve(maxSize * maxSize);

  KK->zero(); // Set to zero all the entries of the Global Matrix

  // element loop: each process loops only on the elements that owns
  for (int iel = msh->_elementOffset[iproc]; iel < msh->_elementOffset[iproc + 1]; iel++) {

    short unsigned ielGeom = msh->GetElementType(iel);      // element geometry type

    unsigned nDofsU = msh->GetElementDofNumber(iel, solUType);      // number of solution element dofs
    unsigned nDofsX = msh->GetElementDofNumber(iel, crdXType);      // number of solution element dofs
    unsigned nDofsV = msh->GetElementDofNumber(iel, solVType);
    // resize local arrays
    sysDof.resize(nDofsU);
    solU.resize(nDofsU);

    sysDof.resize(nDofsV);
    solU.resize(nDofsV);

    for (unsigned  k = 0; k < dim; k++) {
      crdX[k].resize(nDofsX);
    }

    aResU.assign(nDofsU, 0);

    aResV.assign(nDofsV, 0);

    // local storage of global mapping and solution
    for (unsigned i = 0; i < nDofsU; i++) {
      unsigned solUDof = msh->GetSolutionDof(i, iel, solUType);    // local to global mapping of the solution U
      solU[i] = (*sol->_Sol[solUIndex])(solUDof);      // value of the solution U in the dofs
      sysDof[i] = pdeSys->GetSystemDof(solUIndex, solUPdeIndex, i, iel);    // local to global mapping between solution U and system
    }

     for (unsigned i = 0; i < nDofsV; i++) {
      unsigned solVDof = msh->GetSolutionDof(i, iel, solVType);
      solV[i] = (*sol->_Sol[solVIndex])(solVDof);
      sysDof[i+nDofsU] = pdeSys->GetSystemDof(solVIndex, solVPdeIndex, i, iel);
    }

    // local storage of coordinates
    for (unsigned i = 0; i < nDofsX; i++) {
      unsigned coordXDof  = msh->GetSolutionDof(i, iel, crdXType);   // local to global mapping of the coordinate X[dim]

      for (unsigned k = 0; k < dim; k++) {
        crdX[k][i] = (*msh->_topology->_Sol[k])(coordXDof);      // value of the solution X[dim]
      }
    }

    s.new_recording();

    // *** Gauss point loop *** //
    for (unsigned ig = 0; ig < msh->_finiteElement[ielGeom][solUType]->GetGaussPointNumber(); ig++) {
      // *** get gauss point weight, test function and test function partial derivatives ***
      msh->_finiteElement[ielGeom][solUType]->Jacobian(crdX, ig, weight, phi, phi_x, phi_xx);
      msh->_finiteElement[ielGeom][solVType]->Jacobian(crdX, ig, weight, phiV, phiV_x, phiV_xx);

      adept::adouble solUig = 0; // solution U in the gauss point
      vector < adept::adouble > gradSolUig(dim, 0.); // gradient of solution U in the gauss point

      adept::adouble solVig = 0; // solution V in the gauss point
      vector < adept::adouble > gradSolVig(dim, 0.); // gradient of solution U in the gauss point

      for (unsigned i = 0; i < nDofsU; i++) {
        solUig += phi[i] * solU[i];

        for (unsigned j = 0; j < dim; j++) {
          gradSolUig[j] += phi_x[i * dim + j] * solU[i];
        }
      }

      for (unsigned i = 0; i < nDofsV; i++) {
        solVig += phiV[i] * solV[i];

        for (unsigned j = 0; j < dim; j++) {
          gradSolVig[j] += phiV_x[i * dim + j] * solV[i];
        }
      }
      double nu = 1.;

      // *** phiU_i loop ***
      for (unsigned i = 0; i < nDofsU; i++) {
        adept::adouble LaplaceU = 0.;

        for (unsigned j = 0; j < dim; j++) {
          LaplaceU +=  nu * phi_x[i * dim + j] * gradSolUig[j];
        }

        aResU[i] += (phi[i] - LaplaceU) * weight;

      } // end phiU_i loop

      for (unsigned i = 0; i < nDofsV; i++) {
        adept::adouble LaplaceV = 0.;

        for (unsigned j = 0; j < dim; j++) {
          LaplaceV +=  nu * phiV_x[i * dim + j] * gradSolVig[j];
        }

        aResV[i] += (phiV[i]*solU[i] - LaplaceV) * weight;

      } // end phiV_i loop

    } // end gauss point loop

    // } // endif single element not refined or fine grid loop

    //--------------------------------------------------------------------------------------------------------
    // Add the local Matrix/Vector into the global Matrix/Vector

    //copy the value of the adept::adoube aRes in double Res and store them in RES
    Res.resize(nDofsU*2);    //resize

    for (int i = 0; i < nDofsU; i++) {
      Res[i] = -aResU[i].value();
    }

    for (int i = 0; i < nDofsV; i++) {
      Res[i+nDofsU] = -aResV[i].value();
    }

    RES->add_vector_blocked(Res, sysDof);

    //Extarct and store the Jacobian

    Jac.resize(nDofsU * nDofsU);
    // define the dependent variables
    s.dependent(&aResU[0], nDofsU);

    // define the independent variables
    s.independent(&solU[0], nDofsU);

    // get the and store jacobian matrix (row-major)
    s.jacobian(&Jac[0] , true);
    KK->add_matrix_blocked(Jac, sysDof, sysDof);

    s.clear_independents();
    s.clear_dependents();

  } //end element loop for each process

  RES->close();

  KK->close();

  // ***************** END ASSEMBLY *******************
}<|endoftext|>


<commit_before>
#include "CAssetManager.h"

namespace ion
{

	void CAssetManager::Init(CGraphicsAPI * GraphicsAPI)
	{}

	SharedPointer<Graphics::IShaderProgram> CAssetManager::LoadShader(string const & Name)
	{
		if (! GraphicsAPI)
		{
			Log::Error("CAssetManager being used without being initialized, Shader '%s' will not be loaded.", Name);
			return nullptr;
		}

		for (string AssetPath : AssetPaths)
		{
			if (! File::Exists(AssetPath + ShaderPath + Name + ".vert"))
			{
				continue;
			}

			SharedPointer<Graphics::IVertexShader> VertexShader = GraphicsAPI->CreateVertexShaderFromFile(AssetPath + ShaderPath + Name + ".vert");
			SharedPointer<Graphics::IPixelShader> PixelShader = GraphicsAPI->CreatePixelShaderFromFile(AssetPath + ShaderPath + Name + ".frag");

			if (! VertexShader)
			{
				Log::Error("Failed to compile vertex shader '%s'", Name);
				return nullptr;
			}

			if (! PixelShader)
			{
				Log::Error("Failed to compile pixel shader '%s'", Name);
				return nullptr;
			}

			SharedPointer<Graphics::IShaderProgram> ShaderProgram = GraphicsAPI->CreateShaderProgram();
			ShaderProgram->SetVertexStage(VertexShader);
			ShaderProgram->SetPixelStage(PixelShader);

			return ShaderProgram;
		}

		Log::Error("Cannot find shader file in any asset directory: '%s'", Name);
		return nullptr;
	}

	SharedPointer<Graphics::ITexture2D> CAssetManager::LoadTexture(string const & FileName, Graphics::ITexture::EMipMaps const MipMaps)
	{
		if (! GraphicsAPI)
		{
			Log::Error("CAssetManager being used without being initialized, Texture '%s' will not be loaded.", FileName);
			return nullptr;
		}

		for (string AssetPath : AssetPaths)
		{
			if (! File::Exists(AssetPath + TexturePath + FileName))
			{
				continue;
			}

			CImage * Image = CImage::Load(AssetPath + TexturePath + FileName);
			if (Image)
			{
				return GraphicsAPI->CreateTexture2D(Image, MipMaps);
			}
			else
			{
				return nullptr;
			}
		}

		Log::Error("Cannot find image file in any asset directory: '%s'", FileName);
		return nullptr;
	}

	SharedPointer<Graphics::ITexture3D> CAssetManager::Load3DTexture(const std::vector<string> & FileNames, Graphics::ITexture::EMipMaps const MipMaps)
	{
		if (! GraphicsAPI)
		{
			Log::Error("CAssetManager being used without being initialized, Textures will not be loaded");
			return nullptr;
		}
		std::vector<CImage *> ImgArr;
		vec2u setSize(0,0);

		for(string FileName : FileNames)
		{
			for (string AssetPath : AssetPaths)
			{
				if (! File::Exists(AssetPath + TexturePath + FileName))
				{
					continue;
				}

				CImage * Image = CImage::Load(AssetPath + TexturePath + FileName);

				if (Image)
				{
					if(setSize[0] == 0)
					{
						setSize = Image->GetSize();
					}
					else
					{
						assert(Image->GetSize() == setSize);
					}
					ImgArr.push_back(Image);
				}
				else
				{
					return nullptr;
					Log::Error("Cannot find image file in any asset directory: '%s'", FileName);

				}
			}
		}
		Graphics::ITexture::EFormatComponents Format = Graphics::ITexture::EFormatComponents::R;

		switch (ImgArr[0]->GetChannels())
		{
		case 2:
			Format = Graphics::ITexture::EFormatComponents::RG;
			break;
		case 3:
			Format = Graphics::ITexture::EFormatComponents::RGB;
			break;
		case 4:
			Format = Graphics::ITexture::EFormatComponents::RGBA;
			break;
		}
		vec3u size3D(setSize[0],setSize[1],ImgArr.size());
		//Load and combine data

		SharedPointer<Graphics::ITexture3D> Texture3D = GraphicsAPI->CreateTexture3D(size3D,MipMaps,Format,Graphics::ITexture::EInternalFormatType::Fix8);
		for(int i = 0; i < ImgArr.size(); i++)
		{
			CImage * ImagePtr  = ImgArr[i];
			Texture3D->UploadSubRegion(
				ImagePtr->GetData(),
				vec3u(0,0,i),
				vec3u(setSize[0],setSize[1],1),
				Format,
				Graphics::EScalarType::UnsignedInt8);
		}
		return Texture3D;
	}

	SharedPointer<Graphics::ITextureCubeMap> CAssetManager::LoadCubeMapTexture(string const & FileNameLeft, string const & FileNameRight, string const & FileNameUp, string const & FileNameDown, string const & FileNameFront, string const & FileNameBack, Graphics::ITexture::EMipMaps const MipMaps)
	{
		if (! GraphicsAPI)
		{
			Log::Error("CAssetManager being used without being initialized, Texture '%s' etc. will not be loaded.", FileNameLeft);
			return nullptr;
		}

		vector<string> FileNames;
		FileNames.push_back(FileNameLeft);
		FileNames.push_back(FileNameRight);
		FileNames.push_back(FileNameUp);
		FileNames.push_back(FileNameDown);
		FileNames.push_back(FileNameFront);
		FileNames.push_back(FileNameBack);

		vector<CImage *> Images;
		Images.resize(6, nullptr);

		for (int i = 0; i < 6; ++ i)
		{
			for (string AssetPath : AssetPaths)
			{
				if (! File::Exists(AssetPath + TexturePath + FileNames[i]))
				{
					continue;
				}

				CImage * Image = CImage::Load(AssetPath + TexturePath + FileNames[i]);
				if (Image)
				{
					Image->FlipY();
					Images[i] = Image;
					break;
				}
				else
				{
					Log::Error("Failed to open image: '%s'", FileNames[i]);
					return nullptr;
				}
			}

			if (! Images[i])
			{
				Log::Error("Cannot find image file in any asset directory: '%s'", FileNames[i]);
				return nullptr;
			}
		}

		return GraphicsAPI->CreateTextureCubeMap(Images, MipMaps);
	}

	Scene::CSimpleMesh * CAssetManager::LoadMesh(string const & FileName)
	{
		if (! GraphicsAPI)
		{
			Log::Error("CAssetManager being used without being initialized, Texture '%s' will not be loaded.", FileName);
			return nullptr;
		}

		for (string AssetPath : AssetPaths)
		{
			if (! File::Exists(AssetPath + MeshPath + FileName))
			{
				continue;
			}

			vector<Scene::CSimpleMesh *> Shapes = Scene::CGeometryCreator::LoadOBJFile(AssetPath + MeshPath + FileName, AssetPath + MeshPath);

			if (Shapes.size() == 0)
			{
				Log::Error("Failed to load mesh: %s", FileName);
				return nullptr;
			}
			else if (Shapes.size() > 1)
			{
				Log::Error("Mesh contains %d shapes but only one was expected: %s", Shapes.size(), FileName);
			}

			return Shapes[0];
		}

		Log::Error("Cannot find mesh file in any asset directory: '%s'", FileName);
		return nullptr;
	}

	vector<Scene::CSimpleMesh *> CAssetManager::LoadMeshes(string const & FileName)
	{
		vector<Scene::CSimpleMesh *> Meshes;

		if (! GraphicsAPI)
		{
			Log::Error("CAssetManager being used without being initialized, Texture '%s' will not be loaded.", FileName);
			return Meshes;
		}

		for (string AssetPath : AssetPaths)
		{
			if (! File::Exists(AssetPath + MeshPath + FileName))
			{
				continue;
			}

			Meshes = Scene::CGeometryCreator::LoadOBJFile(AssetPath + MeshPath + FileName, AssetPath + MeshPath);

			if (Meshes.size() == 0)
			{
				Log::Error("Failed to load mesh: %s", FileName);
				return Meshes;
			}

			return Meshes;
		}

		Log::Error("Cannot find mesh file in any asset directory: '%s'", FileName);
		return Meshes;
	}

	void CAssetManager::AddAssetPath(string const & Path)
	{
		AssetPaths.push_back(Path + "/");
	}

	void CAssetManager::SetTexturePath(string const & Path)
	{
		TexturePath = Path + "/";
	}

	void CAssetManager::SetShaderPath(string const & Path)
	{
		ShaderPath = Path + "/";
	}

	void CAssetManager::SetMeshPath(string const & Path)
	{
		MeshPath = Path + "/";
	}

}
<commit_msg>[ionApplication] Fix compiler warning<commit_after>
#include "CAssetManager.h"

namespace ion
{

	void CAssetManager::Init(CGraphicsAPI * GraphicsAPI)
	{}

	SharedPointer<Graphics::IShaderProgram> CAssetManager::LoadShader(string const & Name)
	{
		if (! GraphicsAPI)
		{
			Log::Error("CAssetManager being used without being initialized, Shader '%s' will not be loaded.", Name);
			return nullptr;
		}

		for (string AssetPath : AssetPaths)
		{
			if (! File::Exists(AssetPath + ShaderPath + Name + ".vert"))
			{
				continue;
			}

			SharedPointer<Graphics::IVertexShader> VertexShader = GraphicsAPI->CreateVertexShaderFromFile(AssetPath + ShaderPath + Name + ".vert");
			SharedPointer<Graphics::IPixelShader> PixelShader = GraphicsAPI->CreatePixelShaderFromFile(AssetPath + ShaderPath + Name + ".frag");

			if (! VertexShader)
			{
				Log::Error("Failed to compile vertex shader '%s'", Name);
				return nullptr;
			}

			if (! PixelShader)
			{
				Log::Error("Failed to compile pixel shader '%s'", Name);
				return nullptr;
			}

			SharedPointer<Graphics::IShaderProgram> ShaderProgram = GraphicsAPI->CreateShaderProgram();
			ShaderProgram->SetVertexStage(VertexShader);
			ShaderProgram->SetPixelStage(PixelShader);

			return ShaderProgram;
		}

		Log::Error("Cannot find shader file in any asset directory: '%s'", Name);
		return nullptr;
	}

	SharedPointer<Graphics::ITexture2D> CAssetManager::LoadTexture(string const & FileName, Graphics::ITexture::EMipMaps const MipMaps)
	{
		if (! GraphicsAPI)
		{
			Log::Error("CAssetManager being used without being initialized, Texture '%s' will not be loaded.", FileName);
			return nullptr;
		}

		for (string AssetPath : AssetPaths)
		{
			if (! File::Exists(AssetPath + TexturePath + FileName))
			{
				continue;
			}

			CImage * Image = CImage::Load(AssetPath + TexturePath + FileName);
			if (Image)
			{
				return GraphicsAPI->CreateTexture2D(Image, MipMaps);
			}
			else
			{
				return nullptr;
			}
		}

		Log::Error("Cannot find image file in any asset directory: '%s'", FileName);
		return nullptr;
	}

	SharedPointer<Graphics::ITexture3D> CAssetManager::Load3DTexture(const std::vector<string> & FileNames, Graphics::ITexture::EMipMaps const MipMaps)
	{
		if (! GraphicsAPI)
		{
			Log::Error("CAssetManager being used without being initialized, Textures will not be loaded");
			return nullptr;
		}
		std::vector<CImage *> ImgArr;
		vec2u setSize(0,0);

		for(string FileName : FileNames)
		{
			for (string AssetPath : AssetPaths)
			{
				if (! File::Exists(AssetPath + TexturePath + FileName))
				{
					continue;
				}

				CImage * Image = CImage::Load(AssetPath + TexturePath + FileName);

				if (Image)
				{
					if(setSize[0] == 0)
					{
						setSize = Image->GetSize();
					}
					else
					{
						assert(Image->GetSize() == setSize);
					}
					ImgArr.push_back(Image);
				}
				else
				{
					return nullptr;
					Log::Error("Cannot find image file in any asset directory: '%s'", FileName);

				}
			}
		}
		Graphics::ITexture::EFormatComponents Format = Graphics::ITexture::EFormatComponents::R;

		switch (ImgArr[0]->GetChannels())
		{
		case 2:
			Format = Graphics::ITexture::EFormatComponents::RG;
			break;
		case 3:
			Format = Graphics::ITexture::EFormatComponents::RGB;
			break;
		case 4:
			Format = Graphics::ITexture::EFormatComponents::RGBA;
			break;
		}
		vec3u size3D(setSize[0], setSize[1], (uint) ImgArr.size());
		//Load and combine data

		SharedPointer<Graphics::ITexture3D> Texture3D = GraphicsAPI->CreateTexture3D(size3D,MipMaps,Format,Graphics::ITexture::EInternalFormatType::Fix8);
		for(int i = 0; i < ImgArr.size(); i++)
		{
			CImage * ImagePtr  = ImgArr[i];
			Texture3D->UploadSubRegion(
				ImagePtr->GetData(),
				vec3u(0,0,i),
				vec3u(setSize[0],setSize[1],1),
				Format,
				Graphics::EScalarType::UnsignedInt8);
		}
		return Texture3D;
	}

	SharedPointer<Graphics::ITextureCubeMap> CAssetManager::LoadCubeMapTexture(string const & FileNameLeft, string const & FileNameRight, string const & FileNameUp, string const & FileNameDown, string const & FileNameFront, string const & FileNameBack, Graphics::ITexture::EMipMaps const MipMaps)
	{
		if (! GraphicsAPI)
		{
			Log::Error("CAssetManager being used without being initialized, Texture '%s' etc. will not be loaded.", FileNameLeft);
			return nullptr;
		}

		vector<string> FileNames;
		FileNames.push_back(FileNameLeft);
		FileNames.push_back(FileNameRight);
		FileNames.push_back(FileNameUp);
		FileNames.push_back(FileNameDown);
		FileNames.push_back(FileNameFront);
		FileNames.push_back(FileNameBack);

		vector<CImage *> Images;
		Images.resize(6, nullptr);

		for (int i = 0; i < 6; ++ i)
		{
			for (string AssetPath : AssetPaths)
			{
				if (! File::Exists(AssetPath + TexturePath + FileNames[i]))
				{
					continue;
				}

				CImage * Image = CImage::Load(AssetPath + TexturePath + FileNames[i]);
				if (Image)
				{
					Image->FlipY();
					Images[i] = Image;
					break;
				}
				else
				{
					Log::Error("Failed to open image: '%s'", FileNames[i]);
					return nullptr;
				}
			}

			if (! Images[i])
			{
				Log::Error("Cannot find image file in any asset directory: '%s'", FileNames[i]);
				return nullptr;
			}
		}

		return GraphicsAPI->CreateTextureCubeMap(Images, MipMaps);
	}

	Scene::CSimpleMesh * CAssetManager::LoadMesh(string const & FileName)
	{
		if (! GraphicsAPI)
		{
			Log::Error("CAssetManager being used without being initialized, Texture '%s' will not be loaded.", FileName);
			return nullptr;
		}

		for (string AssetPath : AssetPaths)
		{
			if (! File::Exists(AssetPath + MeshPath + FileName))
			{
				continue;
			}

			vector<Scene::CSimpleMesh *> Shapes = Scene::CGeometryCreator::LoadOBJFile(AssetPath + MeshPath + FileName, AssetPath + MeshPath);

			if (Shapes.size() == 0)
			{
				Log::Error("Failed to load mesh: %s", FileName);
				return nullptr;
			}
			else if (Shapes.size() > 1)
			{
				Log::Error("Mesh contains %d shapes but only one was expected: %s", Shapes.size(), FileName);
			}

			return Shapes[0];
		}

		Log::Error("Cannot find mesh file in any asset directory: '%s'", FileName);
		return nullptr;
	}

	vector<Scene::CSimpleMesh *> CAssetManager::LoadMeshes(string const & FileName)
	{
		vector<Scene::CSimpleMesh *> Meshes;

		if (! GraphicsAPI)
		{
			Log::Error("CAssetManager being used without being initialized, Texture '%s' will not be loaded.", FileName);
			return Meshes;
		}

		for (string AssetPath : AssetPaths)
		{
			if (! File::Exists(AssetPath + MeshPath + FileName))
			{
				continue;
			}

			Meshes = Scene::CGeometryCreator::LoadOBJFile(AssetPath + MeshPath + FileName, AssetPath + MeshPath);

			if (Meshes.size() == 0)
			{
				Log::Error("Failed to load mesh: %s", FileName);
				return Meshes;
			}

			return Meshes;
		}

		Log::Error("Cannot find mesh file in any asset directory: '%s'", FileName);
		return Meshes;
	}

	void CAssetManager::AddAssetPath(string const & Path)
	{
		AssetPaths.push_back(Path + "/");
	}

	void CAssetManager::SetTexturePath(string const & Path)
	{
		TexturePath = Path + "/";
	}

	void CAssetManager::SetShaderPath(string const & Path)
	{
		ShaderPath = Path + "/";
	}

	void CAssetManager::SetMeshPath(string const & Path)
	{
		MeshPath = Path + "/";
	}

}
<|endoftext|>