<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Log$
 * Revision 1.8  2002/11/20 20:28:17  peiyongz
 * fix to warning C4018: '>' : signed/unsigned mismatch
 *
 * Revision 1.7  2002/11/12 17:27:49  tng
 * DOM Message: add new domain for DOM Messages.
 *
 * Revision 1.6  2002/11/04 22:24:43  peiyongz
 * Locale setting for message loader
 *
 * Revision 1.5  2002/11/04 15:10:40  tng
 * C++ Namespace Support.
 *
 * Revision 1.4  2002/10/10 21:07:55  peiyongz
 * load resource files using environement vars and base name
 *
 * Revision 1.3  2002/10/02 17:08:50  peiyongz
 * XMLString::equals() to replace XMLString::compareString()
 *
 * Revision 1.2  2002/09/30 22:20:40  peiyongz
 * Build with ICU MsgLoader
 *
 * Revision 1.1.1.1  2002/02/01 22:22:19  peiyongz
 * sane_include
 *
 * Revision 1.7  2002/01/21 14:52:25  tng
 * [Bug 5847] ICUMsgLoader can't be compiled with gcc 3.0.3 and ICU2.  And also fix the memory leak introduced by Bug 2730 fix.
 *
 * Revision 1.6  2001/11/01 23:39:18  jasons
 * 2001-11-01  Jason E. Stewart  <jason@openinformatics.com>
 *
 * 	* src/util/MsgLoaders/ICU/ICUMsgLoader.hpp (Repository):
 * 	* src/util/MsgLoaders/ICU/ICUMsgLoader.cpp (Repository):
 * 	Updated to compile with ICU-1.8.1
 *
 * Revision 1.5  2000/03/02 19:55:14  roddey
 * This checkin includes many changes done while waiting for the
 * 1.1.0 code to be finished. I can't list them all here, but a list is
 * available elsewhere.
 *
 * Revision 1.4  2000/02/06 07:48:21  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.3  2000/01/19 00:58:38  roddey
 * Update to support new ICU 1.4 release.
 *
 * Revision 1.2  1999/11/19 21:24:03  aruna1
 * incorporated ICU 1.3.1 related changes int he file
 *
 * Revision 1.1.1.1  1999/11/09 01:07:23  twl
 * Initial checkin
 *
 * Revision 1.4  1999/11/08 20:45:26  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLMsgLoader.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/util/Janitor.hpp>
#include "ICUMsgLoader.hpp"

#include "string.h"
#include <stdio.h>
#include <stdlib.h>

XERCES_CPP_NAMESPACE_BEGIN

// ---------------------------------------------------------------------------
//  Local static methods
// ---------------------------------------------------------------------------

// ---------------------------------------------------------------------------
//  Public Constructors and Destructor
// ---------------------------------------------------------------------------
ICUMsgLoader::ICUMsgLoader(const XMLCh* const  msgDomain)
:fLocaleBundle(0)
,fDomainBundle(0)
{
    /***
	    Validate msgDomain
    ***/
    if (!XMLString::equals(msgDomain, XMLUni::fgXMLErrDomain)    &&
        !XMLString::equals(msgDomain, XMLUni::fgExceptDomain)    &&
        !XMLString::equals(msgDomain, XMLUni::fgXMLDOMMsgDomain)    &&
        !XMLString::equals(msgDomain, XMLUni::fgValidityDomain)   )
    {
        XMLPlatformUtils::panic(XMLPlatformUtils::Panic_UnknownMsgDomain);
    }

	/***
	     Resolve domainName
	***/
	int          index = XMLString::lastIndexOf(msgDomain, chForwardSlash);
	char*   domainName = XMLString::transcode(&(msgDomain[index + 1]));
    ArrayJanitor<char> jan1(domainName);

    /***
	     Resolve location

	     REVISIT: another approach would be: through some system API
		          which returns the directory of the XercescLib and
		          that directory would be used to locate the
		 		  resource bundle
    ***/
    char locationBuf[1024];
    memset(locationBuf, 0, sizeof locationBuf);
	char *nlsHome = getenv("XERCESC_NLS_HOME");

    if (nlsHome)
	{
		strcpy(locationBuf, nlsHome);
        strcat(locationBuf, U_FILE_SEP_STRING);
	}

    strcat(locationBuf, "XercescErrMsg");

	/***
	    Open the locale-specific resource bundle
	***/
    UErrorCode err = U_ZERO_ERROR;
    fLocaleBundle = ures_open(locationBuf, XMLMsgLoader::getLocale(), &err);
    if (!U_SUCCESS(err) || fLocaleBundle == NULL)
    {
         XMLPlatformUtils::panic(XMLPlatformUtils::Panic_CantLoadMsgDomain);
    }

	/***
	    Open the domain specific resource bundle within
		the locale-specific resource bundle
	***/
	err = U_ZERO_ERROR;
	fDomainBundle = ures_getByKey(fLocaleBundle, domainName, NULL, &err);

	if (!U_SUCCESS(err) || fDomainBundle == NULL)
	{
         XMLPlatformUtils::panic(XMLPlatformUtils::Panic_CantLoadMsgDomain);
	}

}

ICUMsgLoader::~ICUMsgLoader()
{
    ures_close(fDomainBundle);
    ures_close(fLocaleBundle);
}

// ---------------------------------------------------------------------------
//  Implementation of the virtual message loader API
// ---------------------------------------------------------------------------
bool ICUMsgLoader::loadMsg( const   XMLMsgLoader::XMLMsgId  msgToLoad
                          ,         XMLCh* const            toFill
                          , const   unsigned int            maxChars)
{
    UErrorCode   err = U_ZERO_ERROR;
    int32_t      strLen = 0;

    // Assuming array format
    const UChar *name = ures_getStringByIndex(fDomainBundle, (int32_t)msgToLoad-1, &strLen, &err);

    if (!U_SUCCESS(err) || (name == NULL))
    {
        return false;
    }

    int retStrLen = strLen > (int32_t)maxChars ? maxChars : strLen;

    if (sizeof(UChar)==sizeof(XMLCh))
    {
        XMLString::moveChars(toFill, (XMLCh*)name, retStrLen);
        toFill[retStrLen] = (XMLCh) 0;
    }
    else
    {
        XMLCh* retStr = toFill;
        const UChar *srcPtr = name;

        while (retStrLen--)
           *retStr++ = *srcPtr++;

        *retStr = 0;
    }

    return true;
}

bool ICUMsgLoader::loadMsg( const   XMLMsgLoader::XMLMsgId  msgToLoad
                            ,       XMLCh* const            toFill
                            , const unsigned int           maxChars
                            , const XMLCh* const            repText1
                            , const XMLCh* const            repText2
                            , const XMLCh* const            repText3
                            , const XMLCh* const            repText4)
{
    // Call the other version to load up the message
    if (!loadMsg(msgToLoad, toFill, maxChars))
        return false;

    // And do the token replacement
    XMLString::replaceTokens(toFill, maxChars, repText1, repText2, repText3, repText4);
    return true;
}

bool ICUMsgLoader::loadMsg( const   XMLMsgLoader::XMLMsgId  msgToLoad
                            ,       XMLCh* const            toFill
                            , const unsigned int           maxChars
                            , const char* const             repText1
                            , const char* const             repText2
                            , const char* const             repText3
                            , const char* const             repText4)
{
    //
    //  Transcode the provided parameters and call the other version,
    //  which will do the replacement work.
    //
    XMLCh* tmp1 = 0;
    XMLCh* tmp2 = 0;
    XMLCh* tmp3 = 0;
    XMLCh* tmp4 = 0;

    bool bRet = false;
    if (repText1)
        tmp1 = XMLString::transcode(repText1);
    if (repText2)
        tmp2 = XMLString::transcode(repText2);
    if (repText3)
        tmp3 = XMLString::transcode(repText3);
    if (repText4)
        tmp4 = XMLString::transcode(repText4);

    bRet = loadMsg(msgToLoad, toFill, maxChars, tmp1, tmp2, tmp3, tmp4);

    if (tmp1)
        delete [] tmp1;
    if (tmp2)
        delete [] tmp2;
    if (tmp3)
        delete [] tmp3;
    if (tmp4)
        delete [] tmp4;

    return bRet;
}

XERCES_CPP_NAMESPACE_END
<commit_msg>use $XERCESCROOT to search for icu resource bundle if XERCESC_NLS_HOME undefined<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Log$
 * Revision 1.9  2002/12/04 18:11:23  peiyongz
 * use $XERCESCROOT to search for icu resource bundle if XERCESC_NLS_HOME
 * undefined
 *
 * Revision 1.8  2002/11/20 20:28:17  peiyongz
 * fix to warning C4018: '>' : signed/unsigned mismatch
 *
 * Revision 1.7  2002/11/12 17:27:49  tng
 * DOM Message: add new domain for DOM Messages.
 *
 * Revision 1.6  2002/11/04 22:24:43  peiyongz
 * Locale setting for message loader
 *
 * Revision 1.5  2002/11/04 15:10:40  tng
 * C++ Namespace Support.
 *
 * Revision 1.4  2002/10/10 21:07:55  peiyongz
 * load resource files using environement vars and base name
 *
 * Revision 1.3  2002/10/02 17:08:50  peiyongz
 * XMLString::equals() to replace XMLString::compareString()
 *
 * Revision 1.2  2002/09/30 22:20:40  peiyongz
 * Build with ICU MsgLoader
 *
 * Revision 1.1.1.1  2002/02/01 22:22:19  peiyongz
 * sane_include
 *
 * Revision 1.7  2002/01/21 14:52:25  tng
 * [Bug 5847] ICUMsgLoader can't be compiled with gcc 3.0.3 and ICU2.  And also fix the memory leak introduced by Bug 2730 fix.
 *
 * Revision 1.6  2001/11/01 23:39:18  jasons
 * 2001-11-01  Jason E. Stewart  <jason@openinformatics.com>
 *
 * 	* src/util/MsgLoaders/ICU/ICUMsgLoader.hpp (Repository):
 * 	* src/util/MsgLoaders/ICU/ICUMsgLoader.cpp (Repository):
 * 	Updated to compile with ICU-1.8.1
 *
 * Revision 1.5  2000/03/02 19:55:14  roddey
 * This checkin includes many changes done while waiting for the
 * 1.1.0 code to be finished. I can't list them all here, but a list is
 * available elsewhere.
 *
 * Revision 1.4  2000/02/06 07:48:21  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.3  2000/01/19 00:58:38  roddey
 * Update to support new ICU 1.4 release.
 *
 * Revision 1.2  1999/11/19 21:24:03  aruna1
 * incorporated ICU 1.3.1 related changes int he file
 *
 * Revision 1.1.1.1  1999/11/09 01:07:23  twl
 * Initial checkin
 *
 * Revision 1.4  1999/11/08 20:45:26  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLMsgLoader.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/util/Janitor.hpp>
#include "ICUMsgLoader.hpp"

#include "string.h"
#include <stdio.h>
#include <stdlib.h>

XERCES_CPP_NAMESPACE_BEGIN

// ---------------------------------------------------------------------------
//  Local static methods
// ---------------------------------------------------------------------------

// ---------------------------------------------------------------------------
//  Public Constructors and Destructor
// ---------------------------------------------------------------------------
ICUMsgLoader::ICUMsgLoader(const XMLCh* const  msgDomain)
:fLocaleBundle(0)
,fDomainBundle(0)
{
    /***
	    Validate msgDomain
    ***/
    if (!XMLString::equals(msgDomain, XMLUni::fgXMLErrDomain)    &&
        !XMLString::equals(msgDomain, XMLUni::fgExceptDomain)    &&
        !XMLString::equals(msgDomain, XMLUni::fgXMLDOMMsgDomain)    &&
        !XMLString::equals(msgDomain, XMLUni::fgValidityDomain)   )
    {
        XMLPlatformUtils::panic(XMLPlatformUtils::Panic_UnknownMsgDomain);
    }

	/***
	     Resolve domainName
	***/
	int          index = XMLString::lastIndexOf(msgDomain, chForwardSlash);
	char*   domainName = XMLString::transcode(&(msgDomain[index + 1]));
    ArrayJanitor<char> jan1(domainName);

    /***
	     Resolve location

	     REVISIT: another approach would be: through some system API
		          which returns the directory of the XercescLib and
		          that directory would be used to locate the
		 		  resource bundle
    ***/
    char locationBuf[1024];
    memset(locationBuf, 0, sizeof locationBuf);
    char *nlsHome = getenv("XERCESC_NLS_HOME");

    if (nlsHome)
    {
    	strcpy(locationBuf, nlsHome);
        strcat(locationBuf, U_FILE_SEP_STRING);
    }
    else
    {
        char *altHome = getenv("XERCESCROOT");
        if (altHome)
        {
            strcpy(locationBuf, altHome);
            strcat(locationBuf, U_FILE_SEP_STRING);
            strcat(locationBuf, "lib");
            strcat(locationBuf, U_FILE_SEP_STRING);
        }
    }

    strcat(locationBuf, "XercescErrMsg");

	/***
	    Open the locale-specific resource bundle
	***/
    UErrorCode err = U_ZERO_ERROR;
    fLocaleBundle = ures_open(locationBuf, XMLMsgLoader::getLocale(), &err);
    if (!U_SUCCESS(err) || fLocaleBundle == NULL)
    {
         XMLPlatformUtils::panic(XMLPlatformUtils::Panic_CantLoadMsgDomain);
    }

	/***
	    Open the domain specific resource bundle within
		the locale-specific resource bundle
	***/
	err = U_ZERO_ERROR;
	fDomainBundle = ures_getByKey(fLocaleBundle, domainName, NULL, &err);

	if (!U_SUCCESS(err) || fDomainBundle == NULL)
	{
         XMLPlatformUtils::panic(XMLPlatformUtils::Panic_CantLoadMsgDomain);
	}

}

ICUMsgLoader::~ICUMsgLoader()
{
    ures_close(fDomainBundle);
    ures_close(fLocaleBundle);
}

// ---------------------------------------------------------------------------
//  Implementation of the virtual message loader API
// ---------------------------------------------------------------------------
bool ICUMsgLoader::loadMsg( const   XMLMsgLoader::XMLMsgId  msgToLoad
                          ,         XMLCh* const            toFill
                          , const   unsigned int            maxChars)
{
    UErrorCode   err = U_ZERO_ERROR;
    int32_t      strLen = 0;

    // Assuming array format
    const UChar *name = ures_getStringByIndex(fDomainBundle, (int32_t)msgToLoad-1, &strLen, &err);

    if (!U_SUCCESS(err) || (name == NULL))
    {
        return false;
    }

    int retStrLen = strLen > (int32_t)maxChars ? maxChars : strLen;

    if (sizeof(UChar)==sizeof(XMLCh))
    {
        XMLString::moveChars(toFill, (XMLCh*)name, retStrLen);
        toFill[retStrLen] = (XMLCh) 0;
    }
    else
    {
        XMLCh* retStr = toFill;
        const UChar *srcPtr = name;

        while (retStrLen--)
           *retStr++ = *srcPtr++;

        *retStr = 0;
    }

    return true;
}

bool ICUMsgLoader::loadMsg( const   XMLMsgLoader::XMLMsgId  msgToLoad
                            ,       XMLCh* const            toFill
                            , const unsigned int           maxChars
                            , const XMLCh* const            repText1
                            , const XMLCh* const            repText2
                            , const XMLCh* const            repText3
                            , const XMLCh* const            repText4)
{
    // Call the other version to load up the message
    if (!loadMsg(msgToLoad, toFill, maxChars))
        return false;

    // And do the token replacement
    XMLString::replaceTokens(toFill, maxChars, repText1, repText2, repText3, repText4);
    return true;
}

bool ICUMsgLoader::loadMsg( const   XMLMsgLoader::XMLMsgId  msgToLoad
                            ,       XMLCh* const            toFill
                            , const unsigned int           maxChars
                            , const char* const             repText1
                            , const char* const             repText2
                            , const char* const             repText3
                            , const char* const             repText4)
{
    //
    //  Transcode the provided parameters and call the other version,
    //  which will do the replacement work.
    //
    XMLCh* tmp1 = 0;
    XMLCh* tmp2 = 0;
    XMLCh* tmp3 = 0;
    XMLCh* tmp4 = 0;

    bool bRet = false;
    if (repText1)
        tmp1 = XMLString::transcode(repText1);
    if (repText2)
        tmp2 = XMLString::transcode(repText2);
    if (repText3)
        tmp3 = XMLString::transcode(repText3);
    if (repText4)
        tmp4 = XMLString::transcode(repText4);

    bRet = loadMsg(msgToLoad, toFill, maxChars, tmp1, tmp2, tmp3, tmp4);

    if (tmp1)
        delete [] tmp1;
    if (tmp2)
        delete [] tmp2;
    if (tmp3)
        delete [] tmp3;
    if (tmp4)
        delete [] tmp4;

    return bRet;
}

XERCES_CPP_NAMESPACE_END
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_PRODUCTS_BASE_HH
#define DUNE_GDT_PRODUCTS_BASE_HH

#include <dune/stuff/grid/walker.hh>

#include <dune/gdt/assembler/tmp-storage.hh>
#include <dune/gdt/assembler/local/codim0.hh>

#include "interfaces.hh"

namespace Dune {
namespace GDT {
namespace Products {

/**
 *  \todo Derive from SystemAssembler, \see Operators::EllipticG
 */
template <class Traits>
class LocalizableBase : public LocalizableProductInterface<Traits>,
                        public Stuff::Grid::Functor::Codim0<typename Traits::GridViewType>
{
  typedef LocalizableProductInterface<Traits> InterfaceType;

public:
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::RangeType RangeType;
  typedef typename Traits::SourceType SourceType;
  typedef typename Traits::FieldType FieldType;

private:
  typedef typename Traits::LocalOperatorType LocalOperatorType;
  typedef TmpStorageProvider::Matrices<FieldType> TmpMatricesProviderType;

public:
  using typename InterfaceType::EntityType;

public:
  LocalizableBase(const GridViewType& grd_vw, const RangeType& rng, const SourceType& src)
    : grid_view_(grd_vw)
    , range_(rng)
    , source_(src)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , finalized_(false)
    , result_(0)
  {
  }

  LocalizableBase(const GridViewType& grd_vw, const RangeType& rng)
    : grid_view_(grd_vw)
    , range_(rng)
    , source_(range_)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , finalized_(false)
    , result_(0)
  {
  }

  virtual ~LocalizableBase()
  {
  }

  const GridViewType& grid_view() const
  {
    return grid_view_;
  }

  const RangeType& range() const
  {
    return range_;
  }

  const SourceType& source() const
  {
    return source_;
  }

private:
  virtual const LocalOperatorType& local_operator() const = 0;

public:
  virtual void prepare() DS_OVERRIDE
  {
    if (!prepared_) {
      tmp_storage_ = std::unique_ptr<TmpMatricesProviderType>(
          new TmpMatricesProviderType({1, local_operator().numTmpObjectsRequired()}, 1, 1));
      result_   = FieldType(0.0);
      prepared_ = true;
    }
  } // ... prepare()

  FieldType compute_locally(const EntityType& entity)
  {
    assert(prepared_);
    assert(tmp_storage_);
    auto& tmp_storage = tmp_storage_->matrices();
    assert(tmp_storage.size() >= 2);
    assert(tmp_storage[0].size() >= 1);
    auto& local_operator_result = tmp_storage[0][0];
    auto& tmp_matrices          = tmp_storage[1];
    // get the local functions
    const auto local_source_ptr = this->source().local_function(entity);
    const auto local_range_ptr  = this->range().local_function(entity);
    // apply local operator
    local_operator().apply(*local_range_ptr, *local_source_ptr, local_operator_result, tmp_matrices);
    assert(local_operator_result.rows() == 1);
    assert(local_operator_result.cols() == 1);
    return local_operator_result[0][0];
  } // ... compute_locally(...)

  virtual void apply_local(const EntityType& entity) DS_OVERRIDE
  {
    result_ = result_ + compute_locally(entity);
  }

  virtual void finalize() DS_OVERRIDE
  {
    if (!finalized_) {
      FieldType tmp = result_;
      result_       = grid_view_.comm().sum(tmp);
      finalized_    = true;
    }
  }

  FieldType apply2()
  {
    if (!finalized_) {
      Stuff::Grid::Walker<GridViewType> grid_walker(grid_view_);
      grid_walker.add(*this);
      grid_walker.walk();
    }
    return result_;
  }

private:
  const GridViewType& grid_view_;
  const RangeType& range_;
  const SourceType& source_;
  std::unique_ptr<TmpMatricesProviderType> tmp_storage_;
  bool prepared_;
  bool finalized_;
  std::atomic<FieldType> result_;
}; // class LocalizableBase

/**
 *  \todo Derive from SystemAssembler, \see Operators::EllipticG
 */
template <class Traits>
class AssemblableBase : public AssemblableProductInterface<Traits>,
                        public Stuff::Grid::Functor::Codim0<typename Traits::GridViewType>
{
  typedef AssemblableProductInterface<Traits> InterfaceType;

public:
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::RangeSpaceType RangeSpaceType;
  typedef typename Traits::SourceSpaceType SourceSpaceType;
  typedef typename Traits::MatrixType MatrixType;

  typedef typename MatrixType::ScalarType FieldType;

private:
  typedef TmpStorageProvider::Matrices<FieldType> TmpMatricesProviderType;
  typedef typename Traits::LocalOperatorType LocalOperatorType;
  typedef LocalAssembler::Codim0Matrix<LocalOperatorType> LocalAssemblerType;

public:
  using typename InterfaceType::EntityType;

  using InterfaceType::pattern;

  AssemblableBase(MatrixType& mtrx, const RangeSpaceType& rng_spc, const GridViewType& grd_vw,
                  const SourceSpaceType& src_spc)
    : matrix_(mtrx)
    , range_space_(rng_spc)
    , grid_view_(grd_vw)
    , source_space_(src_spc)
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {
  }

  AssemblableBase(MatrixType& mtrx, const RangeSpaceType& rng_spc, const GridViewType& grd_vw)
    : matrix_(mtrx)
    , range_space_(rng_spc)
    , grid_view_(grd_vw)
    , source_space_(range_space_)
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {
  }

  AssemblableBase(MatrixType& mtrx, const RangeSpaceType& rng_spc)
    : matrix_(mtrx)
    , range_space_(rng_spc)
    , grid_view_(*(range_space_->grid_view()))
    , source_space_(range_space_)
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {
  }

  const GridViewType& grid_view() const
  {
    return grid_view_;
  }

  const RangeSpaceType& range_space() const
  {
    return range_space_;
  }

  const SourceSpaceType& source_space() const
  {
    return source_space_;
  }

  MatrixType& matrix()
  {
    return matrix_;
  }

  const MatrixType& matrix() const
  {
    return matrix_;
  }

private:
  virtual const LocalOperatorType& local_operator() const = 0;

public:
  virtual void prepare() DS_OVERRIDE
  {
    if (!assembled_ && !prepared_) {
      local_assembler_ = std::unique_ptr<LocalAssemblerType>(new LocalAssemblerType(local_operator()));
      tmp_storage_ = std::unique_ptr<TmpMatricesProviderType>(
          new TmpMatricesProviderType(local_assembler_->numTmpObjectsRequired(),
                                      range_space_.mapper().maxNumDofs(),
                                      source_space_.mapper().maxNumDofs()));
      prepared_ = true;
    }
  } // ... prepare()

  virtual void apply_local(const EntityType& entity) DS_OVERRIDE
  {
    assert(prepared_);
    assert(local_assembler_);
    assert(tmp_storage_);
    local_assembler_->assembleLocal(
        range_space_, source_space_, entity, matrix_, tmp_storage_->matrices(), tmp_storage_->indices());
  } // ... apply_local(...)

  void assemble()
  {
    if (!assembled_) {
      Stuff::Grid::Walker<GridViewType> grid_walker(grid_view_);
      grid_walker.add(*this);
      grid_walker.walk();
      assembled_ = true;
    }
  } // ... assemble()

  using InterfaceType::apply2;

private:
  MatrixType& matrix_;
  const RangeSpaceType& range_space_;
  const GridViewType& grid_view_;
  const SourceSpaceType& source_space_;
  std::unique_ptr<LocalAssemblerType> local_assembler_;
  std::unique_ptr<TmpMatricesProviderType> tmp_storage_;
  bool prepared_;
  bool assembled_;
}; // class AssemblableBase

} // namespace Products
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_PRODUCTS_BASE_HH
<commit_msg>[products] safer base result summation<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_PRODUCTS_BASE_HH
#define DUNE_GDT_PRODUCTS_BASE_HH

#include <dune/stuff/grid/walker.hh>

#include <dune/gdt/assembler/tmp-storage.hh>
#include <dune/gdt/assembler/local/codim0.hh>

#include "interfaces.hh"

namespace Dune {
namespace GDT {
namespace Products {

/**
 *  \todo Derive from SystemAssembler, \see Operators::EllipticG
 */
template <class Traits>
class LocalizableBase : public LocalizableProductInterface<Traits>,
                        public Stuff::Grid::Functor::Codim0<typename Traits::GridViewType>
{
  typedef LocalizableProductInterface<Traits> InterfaceType;

public:
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::RangeType RangeType;
  typedef typename Traits::SourceType SourceType;
  typedef typename Traits::FieldType FieldType;

private:
  typedef typename Traits::LocalOperatorType LocalOperatorType;
  typedef TmpStorageProvider::Matrices<FieldType> TmpMatricesProviderType;

public:
  using typename InterfaceType::EntityType;

public:
  LocalizableBase(const GridViewType& grd_vw, const RangeType& rng, const SourceType& src)
    : grid_view_(grd_vw)
    , range_(rng)
    , source_(src)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , finalized_(false)
    , result_(0)
  {
  }

  LocalizableBase(const GridViewType& grd_vw, const RangeType& rng)
    : grid_view_(grd_vw)
    , range_(rng)
    , source_(range_)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , finalized_(false)
    , result_(0)
  {
  }

  virtual ~LocalizableBase()
  {
  }

  const GridViewType& grid_view() const
  {
    return grid_view_;
  }

  const RangeType& range() const
  {
    return range_;
  }

  const SourceType& source() const
  {
    return source_;
  }

private:
  virtual const LocalOperatorType& local_operator() const = 0;

public:
  virtual void prepare() DS_OVERRIDE
  {
    if (!prepared_) {
      tmp_storage_ = std::unique_ptr<TmpMatricesProviderType>(
          new TmpMatricesProviderType({1, local_operator().numTmpObjectsRequired()}, 1, 1));
      result_   = FieldType(0.0);
      prepared_ = true;
    }
  } // ... prepare()

  FieldType compute_locally(const EntityType& entity)
  {
    assert(prepared_);
    assert(tmp_storage_);
    auto& tmp_storage = tmp_storage_->matrices();
    assert(tmp_storage.size() >= 2);
    assert(tmp_storage[0].size() >= 1);
    auto& local_operator_result = tmp_storage[0][0];
    auto& tmp_matrices          = tmp_storage[1];
    // get the local functions
    const auto local_source_ptr = this->source().local_function(entity);
    const auto local_range_ptr  = this->range().local_function(entity);
    // apply local operator
    local_operator().apply(*local_range_ptr, *local_source_ptr, local_operator_result, tmp_matrices);
    assert(local_operator_result.rows() == 1);
    assert(local_operator_result.cols() == 1);
    return local_operator_result[0][0];
  } // ... compute_locally(...)

  virtual void apply_local(const EntityType& entity) DS_OVERRIDE
  {
    *result_ += compute_locally(entity);
  }

  virtual void finalize() DS_OVERRIDE
  {
    if (!finalized_) {
      FieldType tmp     = result_.sum();
      finalized_result_ = grid_view_.comm().sum(tmp);
      finalized_        = true;
    }
  }

  FieldType apply2()
  {
    if (!finalized_) {
      Stuff::Grid::Walker<GridViewType> grid_walker(grid_view_);
      grid_walker.add(*this);
      grid_walker.walk();
    }
    return finalized_result_;
  }

private:
  const GridViewType& grid_view_;
  const RangeType& range_;
  const SourceType& source_;
  std::unique_ptr<TmpMatricesProviderType> tmp_storage_;
  bool prepared_;
  bool finalized_;
  DS::PerThreadValue<FieldType> result_;
  FieldType finalized_result_;
}; // class LocalizableBase

/**
 *  \todo Derive from SystemAssembler, \see Operators::EllipticG
 */
template <class Traits>
class AssemblableBase : public AssemblableProductInterface<Traits>,
                        public Stuff::Grid::Functor::Codim0<typename Traits::GridViewType>
{
  typedef AssemblableProductInterface<Traits> InterfaceType;

public:
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::RangeSpaceType RangeSpaceType;
  typedef typename Traits::SourceSpaceType SourceSpaceType;
  typedef typename Traits::MatrixType MatrixType;

  typedef typename MatrixType::ScalarType FieldType;

private:
  typedef TmpStorageProvider::Matrices<FieldType> TmpMatricesProviderType;
  typedef typename Traits::LocalOperatorType LocalOperatorType;
  typedef LocalAssembler::Codim0Matrix<LocalOperatorType> LocalAssemblerType;

public:
  using typename InterfaceType::EntityType;

  using InterfaceType::pattern;

  AssemblableBase(MatrixType& mtrx, const RangeSpaceType& rng_spc, const GridViewType& grd_vw,
                  const SourceSpaceType& src_spc)
    : matrix_(mtrx)
    , range_space_(rng_spc)
    , grid_view_(grd_vw)
    , source_space_(src_spc)
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {
  }

  AssemblableBase(MatrixType& mtrx, const RangeSpaceType& rng_spc, const GridViewType& grd_vw)
    : matrix_(mtrx)
    , range_space_(rng_spc)
    , grid_view_(grd_vw)
    , source_space_(range_space_)
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {
  }

  AssemblableBase(MatrixType& mtrx, const RangeSpaceType& rng_spc)
    : matrix_(mtrx)
    , range_space_(rng_spc)
    , grid_view_(*(range_space_->grid_view()))
    , source_space_(range_space_)
    , local_assembler_(nullptr)
    , tmp_storage_(nullptr)
    , prepared_(false)
    , assembled_(false)
  {
  }

  const GridViewType& grid_view() const
  {
    return grid_view_;
  }

  const RangeSpaceType& range_space() const
  {
    return range_space_;
  }

  const SourceSpaceType& source_space() const
  {
    return source_space_;
  }

  MatrixType& matrix()
  {
    return matrix_;
  }

  const MatrixType& matrix() const
  {
    return matrix_;
  }

private:
  virtual const LocalOperatorType& local_operator() const = 0;

public:
  virtual void prepare() DS_OVERRIDE
  {
    if (!assembled_ && !prepared_) {
      local_assembler_ = std::unique_ptr<LocalAssemblerType>(new LocalAssemblerType(local_operator()));
      tmp_storage_ = std::unique_ptr<TmpMatricesProviderType>(
          new TmpMatricesProviderType(local_assembler_->numTmpObjectsRequired(),
                                      range_space_.mapper().maxNumDofs(),
                                      source_space_.mapper().maxNumDofs()));
      prepared_ = true;
    }
  } // ... prepare()

  virtual void apply_local(const EntityType& entity) DS_OVERRIDE
  {
    assert(prepared_);
    assert(local_assembler_);
    assert(tmp_storage_);
    local_assembler_->assembleLocal(
        range_space_, source_space_, entity, matrix_, tmp_storage_->matrices(), tmp_storage_->indices());
  } // ... apply_local(...)

  void assemble()
  {
    if (!assembled_) {
      Stuff::Grid::Walker<GridViewType> grid_walker(grid_view_);
      grid_walker.add(*this);
      grid_walker.walk();
      assembled_ = true;
    }
  } // ... assemble()

  using InterfaceType::apply2;

private:
  MatrixType& matrix_;
  const RangeSpaceType& range_space_;
  const GridViewType& grid_view_;
  const SourceSpaceType& source_space_;
  std::unique_ptr<LocalAssemblerType> local_assembler_;
  std::unique_ptr<TmpMatricesProviderType> tmp_storage_;
  bool prepared_;
  bool assembled_;
}; // class AssemblableBase

} // namespace Products
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_PRODUCTS_BASE_HH
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_PRODUCTS_BASE_HH
#define DUNE_GDT_PRODUCTS_BASE_HH

#include <dune/stuff/common/memory.hh>
#include <dune/stuff/common/tmp-storage.hh>
#include <dune/stuff/grid/walker.hh>
#include <dune/stuff/la/container/pattern.hh>

#include <dune/gdt/assembler/system.hh>

#include "interfaces.hh"
#include "base-internal.hh"

namespace Dune {
namespace GDT {
namespace Products {

/**
 * \brief Base class for all localizable products.
 *
 *        The purpose of this class is to facilitate the implementation of localizable products (that are based on
 *        local operators) by implementing as much as possible. All you have to do is to implement a class
 *        LocalOperatorProvider, derived from LocalOperatorProviderBase. See the documentation of
 *        \sa LocalOperatorProviderBase for the requirements of your class, depending on the type of local operator you
 *        want to use. We do not use the CRTP machinery here but trust you to implement what is necessarry. Any
 *        additional ctor arguments given to LocalizableBase are forwarded to your implementation of
 *        LocalOperatorProvider. Static checks of GridViewType, RangeType and SourceType are performed in
 *        internal::LocalizableBaseTraits. You can finally implement the product by deriving from this class and
 *        providing the appropriate LocalOperatorProvider. To get an idea see \sa Products::internal::WeightedL2Base in
 *        weightedl2-internal.hh for an example of a LocalOperatorProvider and Products::WeightedL2Localizable in
 *        weightedl2.hh for an example of the final product.
 * \note  If you want to know about the internal workings of this class, take a look at \sa
 *        internal::LocalizableBaseHelper.
 */
template< class LocalOperatorProvider, class RangeImp, class SourceImp >
class LocalizableBase
  : public LocalizableProductInterface< internal::LocalizableBaseTraits< LocalOperatorProvider, RangeImp, SourceImp > >
  , public Stuff::Grid::Walker< typename LocalOperatorProvider::GridViewType >
{
  typedef LocalizableProductInterface
      < internal::LocalizableBaseTraits< LocalOperatorProvider, RangeImp, SourceImp > > ProductBaseType;
  typedef Stuff::Grid::Walker< typename LocalOperatorProvider::GridViewType >           WalkerBaseType;
public:
  typedef internal::LocalizableBaseTraits< LocalOperatorProvider, RangeImp, SourceImp > Traits;

  typedef typename WalkerBaseType::GridViewType     GridViewType;
  typedef typename WalkerBaseType::EntityType       EntityType;
  typedef typename WalkerBaseType::IntersectionType IntersectionType;
  typedef typename ProductBaseType::RangeType  RangeType;
  typedef typename ProductBaseType::SourceType SourceType;
  typedef typename ProductBaseType::FieldType  FieldType;
private:
  typedef internal::LocalizableBaseHelper< LocalOperatorProvider, RangeType, SourceType > HelperType;

public:
  template< class... Args >
  LocalizableBase(const GridViewType& grd_vw, const RangeType& rng, const SourceType& src, Args&& ...args)
    : WalkerBaseType(grd_vw)
    , range_(rng)
    , source_(src)
    , local_operators_(std::forward< Args >(args)...)
    , helper_(*this, local_operators_, range_, source_)
    , walked_(false)
  {}

  template< class... Args >
  LocalizableBase(const GridViewType& grd_vw, const RangeType& rng, Args&& ...args)
    : WalkerBaseType(grd_vw)
    , range_(rng)
    , source_(rng)
    , local_operators_(std::forward< Args >(args)...)
    , helper_(*this, local_operators_, range_, source_)
    , walked_(false)
  {}

  using WalkerBaseType::grid_view;

  const RangeType& range() const
  {
    return range_;
  }

  const SourceType& source() const
  {
    return source_;
  }

  /**
   *       This method can be used to compute a local semi product on one entity, e.g. in the context of error
   *       estimation.
   * \note Calling this method should not alter the result obtained by apply2.
   */
  FieldType compute_locally(const EntityType& entity)
  {
    return helper_.compute_locally(entity);
  }

  /**
   *       This method can be used to compute a local semi product on one intersection, e.g. in the context of error
   *       estimation.
   * \note Calling this method should not alter the result obtained by apply2.
   */
  FieldType compute_locally(const IntersectionType& intersection,
                            const EntityType& inside_entity,
                            const EntityType& outside_entity)
  {
    return helper_.compute_locally(intersection, inside_entity, outside_entity);
  }

  FieldType apply2()
  {
    if (!walked_)
      this->walk();
    return helper_.result();
  } // ... apply2(...)

private:
  const RangeType& range_;
  const SourceType& source_;
  const LocalOperatorProvider local_operators_;
  HelperType helper_;
  bool walked_;
}; // class LocalizableBase

/**
 * \brief Base class for all assembable products.
 *
 *        The purpose of this class is to facilitate the implementation of assembable products (that are based on
 *        local operators) by implementing as much as possible. All you have to do is to implement a class
 *        LocalOperatorProvider, derived from LocalOperatorProviderBase. See the documentation of
 *        \sa LocalOperatorProviderBase for the requirements of your class, depending on the type of local operator you
 *        want to use. We do not use the CRTP machinery here but trust you to implement what is necessarry. Any
 *        additional ctor arguments given to AssemblableBase are forwarded to your implementation of
 *        LocalOperatorProvider. Static checks of MatrixType, RangeSpaceType and SourceSpaceType are performed in
 *        internal::AssemblableBaseTraits. You can finally implement the product by deriving from this class and
 *        providing the appropriate LocalOperatorProvider. To get an idea see \sa Products::internal::WeightedL2Base in
 *        weightedl2-internal.hh for an example of a LocalOperatorProvider and Products::WeightedL2Assemblable in
 *        weightedl2.hh for an example of the final product.
 * \note  If you want to know about the internal workings of this class, take a look at \sa
 *        internal::AssemblableBaseHelper.
 * \note  This class proves an automatic creation of the matrix that is being assembled into. Thus each kind of ctor
 *        exists in two variants (one taking a matrix reference, one not). If you provide an external matrix you are
 *        responsible for the well being of the matrix:
 *        - If this is a sparse matrix it needs to have the correct pattern (can be obtained from this class).
 *        - During assemble values are added to the matrix (not set). Thus it should be empty beforehand or you have to
 *          know what you are doing!
 */
template< class LocalOperatorProvider, class MatrixImp, class RangeSpaceImp, class SourceSpaceImp >
class AssemblableBase
  : DSC::StorageProvider< MatrixImp >
  , public AssemblableProductInterface< internal::AssemblableBaseTraits< LocalOperatorProvider,
                                                                         MatrixImp,
                                                                         RangeSpaceImp,
                                                                         SourceSpaceImp > >
  , public SystemAssembler< RangeSpaceImp, typename LocalOperatorProvider::GridViewType, SourceSpaceImp >
{
  typedef DSC::StorageProvider< MatrixImp >                                                 MatrixProvider;
  typedef AssemblableProductInterface< internal::AssemblableBaseTraits< LocalOperatorProvider,
                                                                        MatrixImp,
                                                                        RangeSpaceImp,
                                                                        SourceSpaceImp > >  ProductBaseType;
  typedef SystemAssembler
      < RangeSpaceImp, typename LocalOperatorProvider::GridViewType, SourceSpaceImp >       AssemblerBaseType;
  typedef AssemblableBase< LocalOperatorProvider, MatrixImp, RangeSpaceImp, SourceSpaceImp > ThisType;
public:
  typedef internal::AssemblableBaseTraits
      < LocalOperatorProvider, MatrixImp, RangeSpaceImp, SourceSpaceImp > Traits;
  typedef typename ProductBaseType::GridViewType    GridViewType;
  typedef typename ProductBaseType::RangeSpaceType  RangeSpaceType;
  typedef typename ProductBaseType::SourceSpaceType SourceSpaceType;
  typedef typename ProductBaseType::MatrixType      MatrixType;
  typedef typename ProductBaseType::FieldType       FieldType;
private:
  typedef internal::AssemblableBaseHelper< ThisType, LocalOperatorProvider > HelperType;

public:
  using ProductBaseType::pattern;

  static Stuff::LA::SparsityPatternDefault pattern(const RangeSpaceType& range_space,
                                                   const SourceSpaceType& source_space,
                                                   const GridViewType& grid_view)
  {
    if (LocalOperatorProvider::has_coupling_operator)
      return range_space.compute_face_and_volume_pattern(grid_view, source_space);
    else if (LocalOperatorProvider::has_volume_operator || LocalOperatorProvider::has_boundary_operator)
      return range_space.compute_volume_pattern(grid_view, source_space);
    else
      return Stuff::LA::SparsityPatternDefault();
  }

  template< class... Args >
  AssemblableBase(MatrixType& mtrx,
                  const RangeSpaceType& rng_spc,
                  const GridViewType& grd_vw,
                  const SourceSpaceType& src_spc,
                  Args&& ...args)
    : MatrixProvider(mtrx)
    , AssemblerBaseType(rng_spc, src_spc, grd_vw)
    , local_operators_(std::forward< Args >(args)...)
    , helper_(*this, MatrixProvider::storage_access(), local_operators_)
    , assembled_(false)
  {}

  template< class... Args >
  AssemblableBase(const RangeSpaceType& rng_spc,
                  const GridViewType& grd_vw,
                  const SourceSpaceType& src_spc,
                  Args&& ...args)
    : MatrixProvider(new MatrixType(rng_spc.mapper().size(),
                                     src_spc.mapper().size(),
                                     pattern(rng_spc, src_spc, grd_vw)))
    , AssemblerBaseType(rng_spc, src_spc, grd_vw)
    , local_operators_(std::forward< Args >(args)...)
    , helper_(*this, MatrixProvider::storage_access(), local_operators_)
    , assembled_(false)
  {}

  template< class... Args >
  AssemblableBase(MatrixType& mtrx, const RangeSpaceType& rng_spc, const GridViewType& grd_vw, Args&& ...args)
    : MatrixProvider(mtrx)
    , AssemblerBaseType(rng_spc, grd_vw)
    , local_operators_(std::forward< Args >(args)...)
    , helper_(*this, MatrixProvider::storage_access(), local_operators_)
    , assembled_(false)
  {}

  template< class... Args >
  AssemblableBase(const RangeSpaceType& rng_spc, const GridViewType& grd_vw, Args&& ...args)
    : MatrixProvider(new MatrixType(rng_spc.mapper().size(), rng_spc.mapper().size(), pattern(rng_spc, grd_vw)))
    , AssemblerBaseType(rng_spc, grd_vw)
    , local_operators_(std::forward< Args >(args)...)
    , helper_(*this, MatrixProvider::storage_access(), local_operators_)
    , assembled_(false)
  {}

  template< class... Args >
  AssemblableBase(MatrixType& mtrx, const RangeSpaceType& rng_spc, Args&& ...args)
    : MatrixProvider(mtrx)
    , AssemblerBaseType(rng_spc)
    , local_operators_(std::forward< Args >(args)...)
    , helper_(*this, MatrixProvider::storage_access(), local_operators_)
    , assembled_(false)
  {}

  template< class... Args >
  AssemblableBase(const RangeSpaceType& rng_spc, Args&& ...args)
    : MatrixProvider(new MatrixType(rng_spc.mapper().size(), rng_spc.mapper().size(), pattern(rng_spc)))
    , AssemblerBaseType(rng_spc)
    , local_operators_(std::forward< Args >(args)...)
    , helper_(*this, MatrixProvider::storage_access(), local_operators_)
    , assembled_(false)
  {}

  using AssemblerBaseType::grid_view;

  const RangeSpaceType& range_space() const
  {
    return AssemblerBaseType::test_space();
  }

  const SourceSpaceType& source_space() const
  {
    return AssemblerBaseType::ansatz_space();
  }

  MatrixType& matrix()
  {
    return MatrixProvider::storage_access();
  }

  const MatrixType& matrix() const
  {
    return MatrixProvider::storage_access();
  }

  void assemble()
  {
    if (!assembled_) {
      AssemblerBaseType::assemble();
      assembled_ = true;
    }
  } // ... assemble()

private:
  const LocalOperatorProvider local_operators_;
  HelperType helper_;
  bool assembled_;
}; // class AssemblableBase

/**
 * \brief Base class for all generic products.
 *
 *        The purpose of this class is to facilitate the implementation of products that are based on a local operator
 *        that is derived from LocalOperator::Codim0Interface by implementing as much as possible. All you have to do is
 *        to implement a class LocalOperatorProvider that provides the following in addition to the requirements of \sa
 *        LocalizableBase:
 *        - it has to be copyable
 *        GenericBase derives from that provided class and forwards any additional ctor arguments to its ctor. A static
 *        check of GridViewType is performed in internal::GenericBaseTraits. You can finally implement the product by
 *        deriving from this class and providing the appropriate LocalOperatorProvider. To get an idea see \sa
 *        Products::internal::WeightedL2Base in l2-internal.hh for an example of a LocalOperatorProvider and
 *        Products::WeightedL2 in l2.hh for an example of the final product. This product is implemented by a creating a
 *        LocalizableBase product of appropriate type for the given source and range.
 */
template< class LocalOperatorProvider >
class GenericBase
  : LocalOperatorProvider
  , public ProductInterface< internal::GenericBaseTraits< LocalOperatorProvider > >
{
  typedef ProductInterface< internal::GenericBaseTraits< LocalOperatorProvider > > BaseType;
public:
  typedef internal::GenericBaseTraits< LocalOperatorProvider > Traits;
  typedef typename BaseType::GridViewType GridViewType;
  typedef typename BaseType::FieldType    FieldType;

  typedef typename GridViewType::template Codim< 0 >::Entity  EntityType;
  typedef typename GridViewType::ctype                        DomainFieldType;
  static const unsigned int                                   dimDomain = GridViewType::dimension;

  template< class... Args >
  GenericBase(const GridViewType& grd_vw, Args&& ...args)
    : LocalOperatorProvider(std::forward< Args >(args)...)
    , grid_view_(grd_vw)
  {}

  const GridViewType& grid_view() const
  {
    return grid_view_;
  }

  template< class RR, int rRR, int rCR, class RS, int rRS, int rCS >
  FieldType apply2(const Stuff::LocalizableFunctionInterface< EntityType, DomainFieldType, dimDomain, RR, rRR, rCR >& range,
                   const Stuff::LocalizableFunctionInterface< EntityType, DomainFieldType, dimDomain, RS, rRS, rCS >& source) const
  {
    typedef Stuff::LocalizableFunctionInterface< EntityType, DomainFieldType, dimDomain, RR, rRR, rCR > RangeType;
    typedef Stuff::LocalizableFunctionInterface< EntityType, DomainFieldType, dimDomain, RS, rRS, rCS > SourceType;
    LocalizableBase< LocalOperatorProvider, RangeType, SourceType > product(grid_view_,
                                                                            range,
                                                                            source,
                                                                            static_cast< const LocalOperatorProvider& >(*this));
    return product.apply2();
  } // ... apply2(...)

private:
  const GridViewType& grid_view_;
}; // class GenericBase

} // namespace Products
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_PRODUCTS_BASE_HH
<commit_msg>[products.base] make copyable<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_PRODUCTS_BASE_HH
#define DUNE_GDT_PRODUCTS_BASE_HH

#include <dune/stuff/common/memory.hh>
#include <dune/stuff/common/tmp-storage.hh>
#include <dune/stuff/grid/walker.hh>
#include <dune/stuff/la/container/pattern.hh>

#include <dune/gdt/assembler/system.hh>

#include "interfaces.hh"
#include "base-internal.hh"

namespace Dune {
namespace GDT {
namespace Products {

/**
 * \brief Base class for all localizable products.
 *
 *        The purpose of this class is to facilitate the implementation of localizable products (that are based on
 *        local operators) by implementing as much as possible. All you have to do is to implement a class
 *        LocalOperatorProvider, derived from LocalOperatorProviderBase. See the documentation of
 *        \sa LocalOperatorProviderBase for the requirements of your class, depending on the type of local operator you
 *        want to use. We do not use the CRTP machinery here but trust you to implement what is necessarry. Any
 *        additional ctor arguments given to LocalizableBase are forwarded to your implementation of
 *        LocalOperatorProvider. Static checks of GridViewType, RangeType and SourceType are performed in
 *        internal::LocalizableBaseTraits. You can finally implement the product by deriving from this class and
 *        providing the appropriate LocalOperatorProvider. To get an idea see \sa Products::internal::WeightedL2Base in
 *        weightedl2-internal.hh for an example of a LocalOperatorProvider and Products::WeightedL2Localizable in
 *        weightedl2.hh for an example of the final product.
 * \note  If you want to know about the internal workings of this class, take a look at \sa
 *        internal::LocalizableBaseHelper.
 */
template< class LocalOperatorProvider, class RangeImp, class SourceImp >
class LocalizableBase
  : public LocalizableProductInterface< internal::LocalizableBaseTraits< LocalOperatorProvider, RangeImp, SourceImp > >
  , public Stuff::Grid::Walker< typename LocalOperatorProvider::GridViewType >
{
  typedef LocalizableBase< LocalOperatorProvider, RangeImp, SourceImp >                 ThisType;
  typedef LocalizableProductInterface
      < internal::LocalizableBaseTraits< LocalOperatorProvider, RangeImp, SourceImp > > ProductBaseType;
  typedef Stuff::Grid::Walker< typename LocalOperatorProvider::GridViewType >           WalkerBaseType;
public:
  typedef internal::LocalizableBaseTraits< LocalOperatorProvider, RangeImp, SourceImp > Traits;

  typedef typename WalkerBaseType::GridViewType     GridViewType;
  typedef typename WalkerBaseType::EntityType       EntityType;
  typedef typename WalkerBaseType::IntersectionType IntersectionType;
  typedef typename ProductBaseType::RangeType  RangeType;
  typedef typename ProductBaseType::SourceType SourceType;
  typedef typename ProductBaseType::FieldType  FieldType;
private:
  typedef internal::LocalizableBaseHelper< LocalOperatorProvider, RangeType, SourceType > HelperType;

public:
  template< class... Args >
  LocalizableBase(const GridViewType& grd_vw, const RangeType& rng, const SourceType& src, Args&& ...args)
    : WalkerBaseType(grd_vw)
    , range_(rng)
    , source_(src)
    , local_operators_(std::forward< Args >(args)...)
    , helper_(*this, local_operators_, range_, source_)
    , walked_(false)
  {}

  template< class... Args >
  LocalizableBase(const GridViewType& grd_vw, const RangeType& rng, Args&& ...args)
    : WalkerBaseType(grd_vw)
    , range_(rng)
    , source_(rng)
    , local_operators_(std::forward< Args >(args)...)
    , helper_(*this, local_operators_, range_, source_)
    , walked_(false)
  {}

  LocalizableBase(const ThisType& other)
    : WalkerBaseType(other.grid_view())
    , range_(other.range_)
    , source_(other.source_)
    , local_operators_(other.local_operators_)
    , helper_(*this, local_operators_, range_, source_)
    , walked_(false)
  {}

  using WalkerBaseType::grid_view;

  const RangeType& range() const
  {
    return range_;
  }

  const SourceType& source() const
  {
    return source_;
  }

  /**
   *       This method can be used to compute a local semi product on one entity, e.g. in the context of error
   *       estimation.
   * \note Calling this method should not alter the result obtained by apply2.
   */
  FieldType compute_locally(const EntityType& entity)
  {
    return helper_.compute_locally(entity);
  }

  /**
   *       This method can be used to compute a local semi product on one intersection, e.g. in the context of error
   *       estimation.
   * \note Calling this method should not alter the result obtained by apply2.
   */
  FieldType compute_locally(const IntersectionType& intersection,
                            const EntityType& inside_entity,
                            const EntityType& outside_entity)
  {
    return helper_.compute_locally(intersection, inside_entity, outside_entity);
  }

  FieldType apply2()
  {
    if (!walked_)
      this->walk();
    return helper_.result();
  } // ... apply2(...)

private:
  const RangeType& range_;
  const SourceType& source_;
  const LocalOperatorProvider local_operators_;
  HelperType helper_;
  bool walked_;
}; // class LocalizableBase

/**
 * \brief Base class for all assembable products.
 *
 *        The purpose of this class is to facilitate the implementation of assembable products (that are based on
 *        local operators) by implementing as much as possible. All you have to do is to implement a class
 *        LocalOperatorProvider, derived from LocalOperatorProviderBase. See the documentation of
 *        \sa LocalOperatorProviderBase for the requirements of your class, depending on the type of local operator you
 *        want to use. We do not use the CRTP machinery here but trust you to implement what is necessarry. Any
 *        additional ctor arguments given to AssemblableBase are forwarded to your implementation of
 *        LocalOperatorProvider. Static checks of MatrixType, RangeSpaceType and SourceSpaceType are performed in
 *        internal::AssemblableBaseTraits. You can finally implement the product by deriving from this class and
 *        providing the appropriate LocalOperatorProvider. To get an idea see \sa Products::internal::WeightedL2Base in
 *        weightedl2-internal.hh for an example of a LocalOperatorProvider and Products::WeightedL2Assemblable in
 *        weightedl2.hh for an example of the final product.
 * \note  If you want to know about the internal workings of this class, take a look at \sa
 *        internal::AssemblableBaseHelper.
 * \note  This class proves an automatic creation of the matrix that is being assembled into. Thus each kind of ctor
 *        exists in two variants (one taking a matrix reference, one not). If you provide an external matrix you are
 *        responsible for the well being of the matrix:
 *        - If this is a sparse matrix it needs to have the correct pattern (can be obtained from this class).
 *        - During assemble values are added to the matrix (not set). Thus it should be empty beforehand or you have to
 *          know what you are doing!
 */
template< class LocalOperatorProvider, class MatrixImp, class RangeSpaceImp, class SourceSpaceImp >
class AssemblableBase
  : DSC::StorageProvider< MatrixImp >
  , public AssemblableProductInterface< internal::AssemblableBaseTraits< LocalOperatorProvider,
                                                                         MatrixImp,
                                                                         RangeSpaceImp,
                                                                         SourceSpaceImp > >
  , public SystemAssembler< RangeSpaceImp, typename LocalOperatorProvider::GridViewType, SourceSpaceImp >
{
  typedef DSC::StorageProvider< MatrixImp >                                                 MatrixProvider;
  typedef AssemblableProductInterface< internal::AssemblableBaseTraits< LocalOperatorProvider,
                                                                        MatrixImp,
                                                                        RangeSpaceImp,
                                                                        SourceSpaceImp > >  ProductBaseType;
  typedef SystemAssembler
      < RangeSpaceImp, typename LocalOperatorProvider::GridViewType, SourceSpaceImp >       AssemblerBaseType;
  typedef AssemblableBase< LocalOperatorProvider, MatrixImp, RangeSpaceImp, SourceSpaceImp > ThisType;
public:
  typedef internal::AssemblableBaseTraits
      < LocalOperatorProvider, MatrixImp, RangeSpaceImp, SourceSpaceImp > Traits;
  typedef typename ProductBaseType::GridViewType    GridViewType;
  typedef typename ProductBaseType::RangeSpaceType  RangeSpaceType;
  typedef typename ProductBaseType::SourceSpaceType SourceSpaceType;
  typedef typename ProductBaseType::MatrixType      MatrixType;
  typedef typename ProductBaseType::FieldType       FieldType;
private:
  typedef internal::AssemblableBaseHelper< ThisType, LocalOperatorProvider > HelperType;

public:
  using ProductBaseType::pattern;

  static Stuff::LA::SparsityPatternDefault pattern(const RangeSpaceType& range_space,
                                                   const SourceSpaceType& source_space,
                                                   const GridViewType& grid_view)
  {
    if (LocalOperatorProvider::has_coupling_operator)
      return range_space.compute_face_and_volume_pattern(grid_view, source_space);
    else if (LocalOperatorProvider::has_volume_operator || LocalOperatorProvider::has_boundary_operator)
      return range_space.compute_volume_pattern(grid_view, source_space);
    else
      return Stuff::LA::SparsityPatternDefault();
  }

  template< class... Args >
  AssemblableBase(MatrixType& mtrx,
                  const RangeSpaceType& rng_spc,
                  const GridViewType& grd_vw,
                  const SourceSpaceType& src_spc,
                  Args&& ...args)
    : MatrixProvider(mtrx)
    , AssemblerBaseType(rng_spc, src_spc, grd_vw)
    , local_operators_(std::forward< Args >(args)...)
    , helper_(*this, MatrixProvider::storage_access(), local_operators_)
    , assembled_(false)
  {}

  template< class... Args >
  AssemblableBase(const RangeSpaceType& rng_spc,
                  const GridViewType& grd_vw,
                  const SourceSpaceType& src_spc,
                  Args&& ...args)
    : MatrixProvider(new MatrixType(rng_spc.mapper().size(),
                                     src_spc.mapper().size(),
                                     pattern(rng_spc, src_spc, grd_vw)))
    , AssemblerBaseType(rng_spc, src_spc, grd_vw)
    , local_operators_(std::forward< Args >(args)...)
    , helper_(*this, MatrixProvider::storage_access(), local_operators_)
    , assembled_(false)
  {}

  template< class... Args >
  AssemblableBase(MatrixType& mtrx, const RangeSpaceType& rng_spc, const GridViewType& grd_vw, Args&& ...args)
    : MatrixProvider(mtrx)
    , AssemblerBaseType(rng_spc, grd_vw)
    , local_operators_(std::forward< Args >(args)...)
    , helper_(*this, MatrixProvider::storage_access(), local_operators_)
    , assembled_(false)
  {}

  template< class... Args >
  AssemblableBase(const RangeSpaceType& rng_spc, const GridViewType& grd_vw, Args&& ...args)
    : MatrixProvider(new MatrixType(rng_spc.mapper().size(), rng_spc.mapper().size(), pattern(rng_spc, grd_vw)))
    , AssemblerBaseType(rng_spc, grd_vw)
    , local_operators_(std::forward< Args >(args)...)
    , helper_(*this, MatrixProvider::storage_access(), local_operators_)
    , assembled_(false)
  {}

  template< class... Args >
  AssemblableBase(MatrixType& mtrx, const RangeSpaceType& rng_spc, Args&& ...args)
    : MatrixProvider(mtrx)
    , AssemblerBaseType(rng_spc)
    , local_operators_(std::forward< Args >(args)...)
    , helper_(*this, MatrixProvider::storage_access(), local_operators_)
    , assembled_(false)
  {}

  template< class... Args >
  AssemblableBase(const RangeSpaceType& rng_spc, Args&& ...args)
    : MatrixProvider(new MatrixType(rng_spc.mapper().size(), rng_spc.mapper().size(), pattern(rng_spc)))
    , AssemblerBaseType(rng_spc)
    , local_operators_(std::forward< Args >(args)...)
    , helper_(*this, MatrixProvider::storage_access(), local_operators_)
    , assembled_(false)
  {}

  using AssemblerBaseType::grid_view;

  const RangeSpaceType& range_space() const
  {
    return AssemblerBaseType::test_space();
  }

  const SourceSpaceType& source_space() const
  {
    return AssemblerBaseType::ansatz_space();
  }

  MatrixType& matrix()
  {
    return MatrixProvider::storage_access();
  }

  const MatrixType& matrix() const
  {
    return MatrixProvider::storage_access();
  }

  void assemble()
  {
    if (!assembled_) {
      AssemblerBaseType::assemble();
      assembled_ = true;
    }
  } // ... assemble()

private:
  const LocalOperatorProvider local_operators_;
  HelperType helper_;
  bool assembled_;
}; // class AssemblableBase

/**
 * \brief Base class for all generic products.
 *
 *        The purpose of this class is to facilitate the implementation of products that are based on a local operator
 *        that is derived from LocalOperator::Codim0Interface by implementing as much as possible. All you have to do is
 *        to implement a class LocalOperatorProvider that provides the following in addition to the requirements of \sa
 *        LocalizableBase:
 *        - it has to be copyable
 *        GenericBase derives from that provided class and forwards any additional ctor arguments to its ctor. A static
 *        check of GridViewType is performed in internal::GenericBaseTraits. You can finally implement the product by
 *        deriving from this class and providing the appropriate LocalOperatorProvider. To get an idea see \sa
 *        Products::internal::WeightedL2Base in l2-internal.hh for an example of a LocalOperatorProvider and
 *        Products::WeightedL2 in l2.hh for an example of the final product. This product is implemented by a creating a
 *        LocalizableBase product of appropriate type for the given source and range.
 */
template< class LocalOperatorProvider >
class GenericBase
  : LocalOperatorProvider
  , public ProductInterface< internal::GenericBaseTraits< LocalOperatorProvider > >
{
  typedef ProductInterface< internal::GenericBaseTraits< LocalOperatorProvider > > BaseType;
public:
  typedef internal::GenericBaseTraits< LocalOperatorProvider > Traits;
  typedef typename BaseType::GridViewType GridViewType;
  typedef typename BaseType::FieldType    FieldType;

  typedef typename GridViewType::template Codim< 0 >::Entity  EntityType;
  typedef typename GridViewType::ctype                        DomainFieldType;
  static const unsigned int                                   dimDomain = GridViewType::dimension;

  template< class... Args >
  GenericBase(const GridViewType& grd_vw, Args&& ...args)
    : LocalOperatorProvider(std::forward< Args >(args)...)
    , grid_view_(grd_vw)
  {}

  const GridViewType& grid_view() const
  {
    return grid_view_;
  }

  template< class RR, int rRR, int rCR, class RS, int rRS, int rCS >
  FieldType apply2(const Stuff::LocalizableFunctionInterface< EntityType, DomainFieldType, dimDomain, RR, rRR, rCR >& range,
                   const Stuff::LocalizableFunctionInterface< EntityType, DomainFieldType, dimDomain, RS, rRS, rCS >& source) const
  {
    typedef Stuff::LocalizableFunctionInterface< EntityType, DomainFieldType, dimDomain, RR, rRR, rCR > RangeType;
    typedef Stuff::LocalizableFunctionInterface< EntityType, DomainFieldType, dimDomain, RS, rRS, rCS > SourceType;
    LocalizableBase< LocalOperatorProvider, RangeType, SourceType > product(grid_view_,
                                                                            range,
                                                                            source,
                                                                            static_cast< const LocalOperatorProvider& >(*this));
    return product.apply2();
  } // ... apply2(...)

private:
  const GridViewType& grid_view_;
}; // class GenericBase

} // namespace Products
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_PRODUCTS_BASE_HH
<|endoftext|>


<commit_before>//==============================================================================
// SingleCellSimulation plugin
//==============================================================================

#include "singlecellsimulationplugin.h"
#include "cellmlmodel.h"
#include "cellmlsupportplugin.h"

//==============================================================================

#include <QFileInfo>
#include <QMainWindow>
#include <QPen>

//==============================================================================

#include "qwt_plot.h"
#include "qwt_plot_grid.h"

//==============================================================================

namespace OpenCOR {
namespace SingleCellSimulation {

//==============================================================================

PLUGININFO_FUNC SingleCellSimulationPluginInfo()
{
    Descriptions descriptions;

    descriptions.insert("en", "A plugin to run single cell simulations");
    descriptions.insert("fr", "Une extension pour excuter des simulations unicellulaires");

    return PluginInfo(PluginInfo::V001,
                      PluginInfo::Gui,
                      PluginInfo::Simulation,
                      true,
                      QStringList() << "CoreSimulation" << "CellMLSupport" << "Qwt",
                      descriptions);
}

//==============================================================================

Q_EXPORT_PLUGIN2(SingleCellSimulation, SingleCellSimulationPlugin)

//==============================================================================

SingleCellSimulationPlugin::SingleCellSimulationPlugin()
{
    // Set our settings

    mGuiSettings->addView(GuiViewSettings::Simulation, 0);
}

//==============================================================================

void SingleCellSimulationPlugin::initialize()
{
    // Create our simulation view widget

    mSimulationView = new QwtPlot(mMainWindow);

    // Hide our simulation view widget since it may not initially be shown in
    // our central widget

    mSimulationView->setVisible(false);

    // Customise our simulation view widget

    mSimulationView->setCanvasBackground(Qt::white);

    // Remove the canvas' border as it otherwise looks odd, not to say ugly,
    // with one

    mSimulationView->setCanvasLineWidth(0);

    // Add a grid to our simulation view widget

    QwtPlotGrid *grid = new QwtPlotGrid;

    grid->setMajPen(QPen(Qt::gray, 0, Qt::DotLine));

    grid->attach(mSimulationView);
}

//==============================================================================

QWidget * SingleCellSimulationPlugin::viewWidget(const QString &pFileName,
                                                 const int &)
{
    // Check that we are dealing with a CellML file and, if so, return our
    // generic simulation view widget

    if (QFileInfo(pFileName).suffix().compare(CellMLSupport::CellmlFileExtension))
        // Not the expected file extension, so...

        return 0;
    else
{
//--- TESTING --- BEGIN ---

        qDebug("=======================================");
        qDebug("%s:", pFileName.toLatin1().constData());

        // Load the CellML model

        CellMLSupport::CellmlModel *cellmlModel = new CellMLSupport::CellmlModel(pFileName);

        // Check the model's validity

        if (cellmlModel->isValid()) {
            // The model is valid, but let's see whether warnings were generated

            int nbOfWarnings = cellmlModel->issues().count();

            if (nbOfWarnings)
                qDebug(" - The model was properly loaded:");
            else
                qDebug(" - The model was properly loaded.");
        } else {
            qDebug(" - The model was NOT properly loaded:");
        }

        // Output any warnings/errors that were generated

        foreach (const CellMLSupport::CellmlModelIssue &issue, cellmlModel->issues()) {
            QString type = QString((issue.type() == CellMLSupport::CellmlModelIssue::Error)?"Error":"Warrning");
            QString message = issue.formattedMessage();
            uint32_t line = issue.line();
            uint32_t column = issue.column();
            QString importedModel = issue.importedModel();

            if (line && column) {
                if (importedModel.isEmpty())
                    qDebug("    [%s at line %s column %s] %s", type.toLatin1().constData(),
                                                               QString::number(issue.line()).toLatin1().constData(),
                                                               QString::number(issue.column()).toLatin1().constData(),
                                                               message.toUtf8().constData());
                else
                    qDebug("    [%s at line %s column %s from imported model %s] %s", type.toLatin1().constData(),
                                                                                QString::number(issue.line()).toLatin1().constData(),
                                                                                QString::number(issue.column()).toLatin1().constData(),
                                                                                importedModel.toLatin1().constData(),
                                                                                message.toUtf8().constData());
            } else {
                if (importedModel.isEmpty())
                    qDebug("    [%s] %s", type.toLatin1().constData(),
                                          message.toUtf8().constData());
                else
                    qDebug("    [%s from imported model %s] %s", type.toLatin1().constData(),
                                                                 importedModel.toLatin1().constData(),
                                                                 message.toUtf8().constData());
            }
        }

        // Get a runtime for the model

        CellMLSupport::CellmlModelRuntime *cellmlModelRuntime = cellmlModel->runtime();

        if (cellmlModelRuntime->isValid()) {
            qDebug(" - The model's runtime was properly generated.");
            qDebug("    [Information] Model type = %s", (cellmlModelRuntime->modelType() == CellMLSupport::CellmlModelRuntime::Ode)?"ODE":"DAE");
        } else {
            qDebug(" - The model's runtime was NOT properly generated:");

            foreach (const CellMLSupport::CellmlModelIssue &issue,
                     cellmlModelRuntime->issues()) {
                QString type = QString((issue.type() == CellMLSupport::CellmlModelIssue::Error)?"Error":"Warrning");
                QString message = issue.formattedMessage();

                qDebug("    [%s] %s", type.toLatin1().constData(),
                                      message.toUtf8().constData());
            }
        }

        // Done with our testing, so...

        delete cellmlModel;

//--- TESTING --- END ---

        // The expected file extension, so return our generic simulation view
        // widget

        return mSimulationView;
}
}

//==============================================================================

QString SingleCellSimulationPlugin::viewName(const int &pViewIndex)
{
    // We have only one view, so return its name otherwise call the GuiInterface
    // implementation of viewName

    switch (pViewIndex) {
    case 0:
        return tr("Single Cell");
    default:
        return GuiInterface::viewName(pViewIndex);
    }
}

//==============================================================================

}   // namespace SingleCellSimulation
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<commit_msg>Getting ready to compute a model, but only for demonstration purposes, so everything will be hard-coded.<commit_after>//==============================================================================
// SingleCellSimulation plugin
//==============================================================================

#include "singlecellsimulationplugin.h"
#include "cellmlmodel.h"
#include "cellmlsupportplugin.h"

//==============================================================================

#include <QFileInfo>
#include <QMainWindow>
#include <QPen>
#include <QVector>

//==============================================================================

#include "qwt_plot.h"
#include "qwt_plot_grid.h"
#include "qwt_plot_curve.h"

//==============================================================================

namespace OpenCOR {
namespace SingleCellSimulation {

//==============================================================================

PLUGININFO_FUNC SingleCellSimulationPluginInfo()
{
    Descriptions descriptions;

    descriptions.insert("en", "A plugin to run single cell simulations");
    descriptions.insert("fr", "Une extension pour excuter des simulations unicellulaires");

    return PluginInfo(PluginInfo::V001,
                      PluginInfo::Gui,
                      PluginInfo::Simulation,
                      true,
                      QStringList() << "CoreSimulation" << "CellMLSupport" << "Qwt",
                      descriptions);
}

//==============================================================================

Q_EXPORT_PLUGIN2(SingleCellSimulation, SingleCellSimulationPlugin)

//==============================================================================

SingleCellSimulationPlugin::SingleCellSimulationPlugin()
{
    // Set our settings

    mGuiSettings->addView(GuiViewSettings::Simulation, 0);
}

//==============================================================================

void SingleCellSimulationPlugin::initialize()
{
    // Create our simulation view widget

    mSimulationView = new QwtPlot(mMainWindow);

    // Hide our simulation view widget since it may not initially be shown in
    // our central widget

    mSimulationView->setVisible(false);

    // Customise our simulation view widget

    mSimulationView->setCanvasBackground(Qt::white);

    // Remove the canvas' border as it otherwise looks odd, not to say ugly,
    // with one

    mSimulationView->setCanvasLineWidth(0);

    // Add a grid to our simulation view widget

    QwtPlotGrid *grid = new QwtPlotGrid;

    grid->setMajPen(QPen(Qt::gray, 0, Qt::DotLine));

    grid->attach(mSimulationView);
}

//==============================================================================

QWidget * SingleCellSimulationPlugin::viewWidget(const QString &pFileName,
                                                 const int &)
{
    // Check that we are dealing with a CellML file and, if so, return our
    // generic simulation view widget

    if (QFileInfo(pFileName).suffix().compare(CellMLSupport::CellmlFileExtension))
        // Not the expected file extension, so...

        return 0;
    else
{
//--- TESTING --- BEGIN ---

        qDebug("=======================================");
        qDebug("%s:", pFileName.toLatin1().constData());

        // Load the CellML model

        CellMLSupport::CellmlModel *cellmlModel = new CellMLSupport::CellmlModel(pFileName);

        // Check the model's validity

        if (cellmlModel->isValid()) {
            // The model is valid, but let's see whether warnings were generated

            int nbOfWarnings = cellmlModel->issues().count();

            if (nbOfWarnings)
                qDebug(" - The model was properly loaded:");
            else
                qDebug(" - The model was properly loaded.");
        } else {
            qDebug(" - The model was NOT properly loaded:");
        }

        // Output any warnings/errors that were generated

        foreach (const CellMLSupport::CellmlModelIssue &issue, cellmlModel->issues()) {
            QString type = QString((issue.type() == CellMLSupport::CellmlModelIssue::Error)?"Error":"Warrning");
            QString message = issue.formattedMessage();
            uint32_t line = issue.line();
            uint32_t column = issue.column();
            QString importedModel = issue.importedModel();

            if (line && column) {
                if (importedModel.isEmpty())
                    qDebug("    [%s at line %s column %s] %s", type.toLatin1().constData(),
                                                               QString::number(issue.line()).toLatin1().constData(),
                                                               QString::number(issue.column()).toLatin1().constData(),
                                                               message.toUtf8().constData());
                else
                    qDebug("    [%s at line %s column %s from imported model %s] %s", type.toLatin1().constData(),
                                                                                QString::number(issue.line()).toLatin1().constData(),
                                                                                QString::number(issue.column()).toLatin1().constData(),
                                                                                importedModel.toLatin1().constData(),
                                                                                message.toUtf8().constData());
            } else {
                if (importedModel.isEmpty())
                    qDebug("    [%s] %s", type.toLatin1().constData(),
                                          message.toUtf8().constData());
                else
                    qDebug("    [%s from imported model %s] %s", type.toLatin1().constData(),
                                                                 importedModel.toLatin1().constData(),
                                                                 message.toUtf8().constData());
            }
        }

        // Get a runtime for the model

        CellMLSupport::CellmlModelRuntime *cellmlModelRuntime = cellmlModel->runtime();

        if (cellmlModelRuntime->isValid()) {
            qDebug(" - The model's runtime was properly generated.");
            qDebug("    [Information] Model type = %s", (cellmlModelRuntime->modelType() == CellMLSupport::CellmlModelRuntime::Ode)?"ODE":"DAE");
        } else {
            qDebug(" - The model's runtime was NOT properly generated:");

            foreach (const CellMLSupport::CellmlModelIssue &issue,
                     cellmlModelRuntime->issues()) {
                QString type = QString((issue.type() == CellMLSupport::CellmlModelIssue::Error)?"Error":"Warrning");
                QString message = issue.formattedMessage();

                qDebug("    [%s] %s", type.toLatin1().constData(),
                                      message.toUtf8().constData());
            }
        }

        // Compute the model

        typedef QVector<double> Doubles;

        static const int NbOfDataPoints = 100;
        static const double Factor      = 6.28/double(NbOfDataPoints-1);

        Doubles xData;
        Doubles yData;

        for (int i = 0; i < NbOfDataPoints; ++i) {
            xData.append(i*Factor);
            yData.append(sin(xData.last()));
        }

        // Add a curve to our view

        QwtPlotCurve *curve = new QwtPlotCurve;

        curve->setRenderHint(QwtPlotItem::RenderAntialiased);
        curve->setPen(QPen(Qt::darkBlue));
        curve->setSamples(xData, yData);

        curve->attach(mSimulationView);

        // Done with our testing, so...

        delete cellmlModel;

//--- TESTING --- END ---

        // The expected file extension, so return our generic simulation view
        // widget

        return mSimulationView;
}
}

//==============================================================================

QString SingleCellSimulationPlugin::viewName(const int &pViewIndex)
{
    // We have only one view, so return its name otherwise call the GuiInterface
    // implementation of viewName

    switch (pViewIndex) {
    case 0:
        return tr("Single Cell");
    default:
        return GuiInterface::viewName(pViewIndex);
    }
}

//==============================================================================

}   // namespace SingleCellSimulation
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<|endoftext|>


<commit_before>#include "gen_exported.h"

namespace gen_exported {

/*******************************************************************************************************************
Copyright (c) 2012 Cycling '74

Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*******************************************************************************************************************/

// global noise generator
Noise noise;
static const int GENLIB_LOOPCOUNT_BAIL = 100000;

// The State struct contains all the state and procedures for the gendsp kernel
typedef struct State {
	CommonState __commonstate;
	double m_resolution_1;
	double samplerate;
	int vectorsize;
	int __exception;
	// re-initialize all member variables;
	inline void reset(double __sr, int __vs) {
		__exception = 0;
		vectorsize = __vs;
		samplerate = __sr;
		m_resolution_1 = 6;
		genlib_reset_complete(this);

	};
	// the signal processing routine;
	inline int perform(t_sample ** __ins, t_sample ** __outs, int __n) {
		vectorsize = __n;
		const t_sample * __in1 = __ins[0];
		t_sample * __out1 = __outs[0];
		t_sample * __out2 = __outs[1];
		if (__exception) {
			return __exception;

		} else if (( (__in1 == 0) || (__out1 == 0) || (__out2 == 0) )) {
			__exception = GENLIB_ERR_NULL_BUFFER;
			return __exception;

		};
		// the main sample loop;
		while ((__n--)) {
			const double in1 = (*(__in1++));
			double mul_50 = (in1 * m_resolution_1);
			double ceil_49 = ceil(mul_50);
			double div_48 = safediv(ceil_49, m_resolution_1);
			double out1 = div_48;
			double add_45 = (mul_50 + 0.5);
			double floor_46 = floor(add_45);
			double sub_44 = (floor_46 - 0.5);
			double div_47 = safediv(sub_44, m_resolution_1);
			double out2 = div_47;
			// assign results to output buffer;
			(*(__out1++)) = out1;
			(*(__out2++)) = out2;

		};
		return __exception;

	};
	inline void set_resolution(double _value) {
		m_resolution_1 = _value;
	};

} State;

///
///	Configuration for the genlib API
///

/// Number of signal inputs and outputs

int gen_kernel_numins = 1;
int gen_kernel_numouts = 2;

int num_inputs() { return gen_kernel_numins; }
int num_outputs() { return gen_kernel_numouts; }
int num_params() { return 1; }

/// Assistive lables for the signal inputs and outputs

const char * gen_kernel_innames[] = { "in1" };
const char * gen_kernel_outnames[] = { "out1", "out2" };

/// Invoke the signal process of a State object

int perform(CommonState *cself, t_sample **ins, long numins, t_sample **outs, long numouts, long n) {
	State * self = (State *)cself;
	return self->perform(ins, outs, n);
}

/// Reset all parameters and stateful operators of a State object

void reset(CommonState *cself) {
	State * self = (State *)cself;
	self->reset(cself->sr, cself->vs);
}

/// Set a parameter of a State object

void setparameter(CommonState *cself, long index, double value, void *ref) {
	State * self = (State *)cself;
	switch (index) {
		case 0: self->set_resolution(value); break;

		default: break;
	}
}

/// Get the value of a parameter of a State object

void getparameter(CommonState *cself, long index, double *value) {
	State *self = (State *)cself;
	switch (index) {
		case 0: *value = self->m_resolution_1; break;

		default: break;
	}
}

/// Allocate and configure a new State object and it's internal CommonState:

void * create(double sr, long vs) {
	State *self = new State;
	self->reset(sr, vs);
	ParamInfo *pi;
	self->__commonstate.inputnames = gen_kernel_innames;
	self->__commonstate.outputnames = gen_kernel_outnames;
	self->__commonstate.numins = gen_kernel_numins;
	self->__commonstate.numouts = gen_kernel_numouts;
	self->__commonstate.sr = sr;
	self->__commonstate.vs = vs;
	self->__commonstate.params = (ParamInfo *)genlib_sysmem_newptr(1 * sizeof(ParamInfo));
	self->__commonstate.numparams = 1;
	// initialize parameter 0 ("m_resolution_1")
	pi = self->__commonstate.params + 0;
	pi->name = "resolution";
	pi->paramtype = GENLIB_PARAMTYPE_FLOAT;
	pi->defaultvalue = self->m_resolution_1;
	pi->defaultref = 0;
	pi->hasinputminmax = false;
	pi->inputmin = 0;
	pi->inputmax = 1;
	pi->hasminmax = true;
	pi->outputmin = 1;
	pi->outputmax = 32;
	pi->exp = 0;
	pi->units = "bits";		// no units defined

	return self;
}

/// Release all resources and memory used by a State object:

void destroy(CommonState *cself) {
	State * self = (State *)cself;
	genlib_sysmem_freeptr(cself->params);

	delete self;
}

} // gen_exported::
<commit_msg>Limit bitcrusher resolution param to 16 max<commit_after>#include "gen_exported.h"

namespace gen_exported {

/*******************************************************************************************************************
Copyright (c) 2012 Cycling '74

Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*******************************************************************************************************************/

// global noise generator
Noise noise;
static const int GENLIB_LOOPCOUNT_BAIL = 100000;

// The State struct contains all the state and procedures for the gendsp kernel
typedef struct State {
	CommonState __commonstate;
	double m_resolution_1;
	double samplerate;
	int vectorsize;
	int __exception;
	// re-initialize all member variables;
	inline void reset(double __sr, int __vs) {
		__exception = 0;
		vectorsize = __vs;
		samplerate = __sr;
		m_resolution_1 = 6;
		genlib_reset_complete(this);

	};
	// the signal processing routine;
	inline int perform(t_sample ** __ins, t_sample ** __outs, int __n) {
		vectorsize = __n;
		const t_sample * __in1 = __ins[0];
		t_sample * __out1 = __outs[0];
		t_sample * __out2 = __outs[1];
		if (__exception) {
			return __exception;

		} else if (( (__in1 == 0) || (__out1 == 0) || (__out2 == 0) )) {
			__exception = GENLIB_ERR_NULL_BUFFER;
			return __exception;

		};
		// the main sample loop;
		while ((__n--)) {
			const double in1 = (*(__in1++));
			double mul_50 = (in1 * m_resolution_1);
			double ceil_49 = ceil(mul_50);
			double div_48 = safediv(ceil_49, m_resolution_1);
			double out1 = div_48;
			double add_45 = (mul_50 + 0.5);
			double floor_46 = floor(add_45);
			double sub_44 = (floor_46 - 0.5);
			double div_47 = safediv(sub_44, m_resolution_1);
			double out2 = div_47;
			// assign results to output buffer;
			(*(__out1++)) = out1;
			(*(__out2++)) = out2;

		};
		return __exception;

	};
	inline void set_resolution(double _value) {
		m_resolution_1 = (_value < 1 ? 1 : (_value > 16 ? 16 : _value));
	};

} State;

///
///	Configuration for the genlib API
///

/// Number of signal inputs and outputs

int gen_kernel_numins = 1;
int gen_kernel_numouts = 2;

int num_inputs() { return gen_kernel_numins; }
int num_outputs() { return gen_kernel_numouts; }
int num_params() { return 1; }

/// Assistive lables for the signal inputs and outputs

const char * gen_kernel_innames[] = { "in1" };
const char * gen_kernel_outnames[] = { "out1", "out2" };

/// Invoke the signal process of a State object

int perform(CommonState *cself, t_sample **ins, long numins, t_sample **outs, long numouts, long n) {
	State * self = (State *)cself;
	return self->perform(ins, outs, n);
}

/// Reset all parameters and stateful operators of a State object

void reset(CommonState *cself) {
	State * self = (State *)cself;
	self->reset(cself->sr, cself->vs);
}

/// Set a parameter of a State object

void setparameter(CommonState *cself, long index, double value, void *ref) {
	State * self = (State *)cself;
	switch (index) {
		case 0: self->set_resolution(value); break;

		default: break;
	}
}

/// Get the value of a parameter of a State object

void getparameter(CommonState *cself, long index, double *value) {
	State *self = (State *)cself;
	switch (index) {
		case 0: *value = self->m_resolution_1; break;

		default: break;
	}
}

/// Allocate and configure a new State object and it's internal CommonState:

void * create(double sr, long vs) {
	State *self = new State;
	self->reset(sr, vs);
	ParamInfo *pi;
	self->__commonstate.inputnames = gen_kernel_innames;
	self->__commonstate.outputnames = gen_kernel_outnames;
	self->__commonstate.numins = gen_kernel_numins;
	self->__commonstate.numouts = gen_kernel_numouts;
	self->__commonstate.sr = sr;
	self->__commonstate.vs = vs;
	self->__commonstate.params = (ParamInfo *)genlib_sysmem_newptr(1 * sizeof(ParamInfo));
	self->__commonstate.numparams = 1;
	// initialize parameter 0 ("m_resolution_1")
	pi = self->__commonstate.params + 0;
	pi->name = "resolution";
	pi->paramtype = GENLIB_PARAMTYPE_FLOAT;
	pi->defaultvalue = self->m_resolution_1;
	pi->defaultref = 0;
	pi->hasinputminmax = false;
	pi->inputmin = 0;
	pi->inputmax = 1;
	pi->hasminmax = true;
	pi->outputmin = 1;
	pi->outputmax = 16;
	pi->exp = 0;
	pi->units = "bits";		// no units defined

	return self;
}

/// Release all resources and memory used by a State object:

void destroy(CommonState *cself) {
	State * self = (State *)cself;
	genlib_sysmem_freeptr(cself->params);

	delete self;
}

} // gen_exported::
<|endoftext|>