<commit_before>#include "WallFrictionChurchillMaterial.h"
#include "WallFrictionModels.h"
#include "Numerics.h"

template <>
InputParameters
validParams<WallFrictionChurchillMaterial>()
{
  InputParameters params = validParams<WallFriction3EqnBaseMaterial>();
  params.addRequiredCoupledVar("rhoA", "Mass equation variable: rho*A");
  params.addRequiredCoupledVar("rhouA", "Momentum equation variable: rho*u*A");
  params.addRequiredCoupledVar("rhoEA", "Total energy equation variable: rho*E*A");
  params.addRequiredCoupledVar("rho", "Density");
  params.addRequiredCoupledVar("vel", "x-component of the velocity");
  params.addRequiredCoupledVar("D_h", "hydraulic diameter");

  params.addRequiredParam<MaterialPropertyName>("Cw", "Drag coefficient material property");
  params.addRequiredParam<MaterialPropertyName>("mu", "Dynamic viscosity material property");

  params.addRequiredParam<Real>("roughness", "Surface roughness");
  params.declareControllable("roughness");
  return params;
}

WallFrictionChurchillMaterial::WallFrictionChurchillMaterial(const InputParameters & parameters)
  : WallFriction3EqnBaseMaterial(parameters)
{
}

void
WallFrictionChurchillMaterial::computeQpProperties()
{
  Real Re = RELAP7::Reynolds(1, _rho[_qp], _vel[_qp], _D_h[_qp], _mu[_qp]);

  _Cw[_qp] = WallFriction::Churchill(Re, _roughness, _D_h[_qp]) * 2. * _rho[_qp] / _D_h[_qp];
  _dCw_drhoA[_qp] = 0;
  _dCw_drhouA[_qp] = 0;
  _dCw_drhoEA[_qp] = 0;
}
<commit_msg>Update to new register methods<commit_after>#include "WallFrictionChurchillMaterial.h"
#include "WallFrictionModels.h"
#include "Numerics.h"

registerMooseObject("RELAP7App", WallFrictionChurchillMaterial);

template <>
InputParameters
validParams<WallFrictionChurchillMaterial>()
{
  InputParameters params = validParams<WallFriction3EqnBaseMaterial>();
  params.addRequiredCoupledVar("rhoA", "Mass equation variable: rho*A");
  params.addRequiredCoupledVar("rhouA", "Momentum equation variable: rho*u*A");
  params.addRequiredCoupledVar("rhoEA", "Total energy equation variable: rho*E*A");
  params.addRequiredCoupledVar("rho", "Density");
  params.addRequiredCoupledVar("vel", "x-component of the velocity");
  params.addRequiredCoupledVar("D_h", "hydraulic diameter");

  params.addRequiredParam<MaterialPropertyName>("Cw", "Drag coefficient material property");
  params.addRequiredParam<MaterialPropertyName>("mu", "Dynamic viscosity material property");

  params.addRequiredParam<Real>("roughness", "Surface roughness");
  params.declareControllable("roughness");
  return params;
}

WallFrictionChurchillMaterial::WallFrictionChurchillMaterial(const InputParameters & parameters)
  : WallFriction3EqnBaseMaterial(parameters)
{
}

void
WallFrictionChurchillMaterial::computeQpProperties()
{
  Real Re = RELAP7::Reynolds(1, _rho[_qp], _vel[_qp], _D_h[_qp], _mu[_qp]);

  _Cw[_qp] = WallFriction::Churchill(Re, _roughness, _D_h[_qp]) * 2. * _rho[_qp] / _D_h[_qp];
  _dCw_drhoA[_qp] = 0;
  _dCw_drhouA[_qp] = 0;
  _dCw_drhoEA[_qp] = 0;
}
<|endoftext|>


<commit_before>//
//  OCTrace.cpp
//  IPAPatch
//
//  Created by wadahana on 01/06/2017.
//  Copyright © 2017. All rights reserved.
//

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <dlfcn.h>
#include <assert.h>
#include <string.h>
#include <pthread.h>
#include <uuid/uuid.h>

#include <objc/objc.h>
#include <objc/runtime.h>
#include <mach/mach.h>
#include <mach-o/dyld_images.h>
#include <mach/vm_map.h>
#include <mach-o/loader.h>
#include <mach-o/nlist.h>
#include <mach-o/fat.h>
#include <mach-o/loader.h>
#include <mach-o/dyld.h>

#import "fishhook.h"

#include "OCTrace.h"
#include "OCTraceImage.h"
#include "OCTraceLogger.h"
#include "OCTraceLocalLogger.h"
#include "OCTraceRemoteLogger.h"
#include <vector>
#include <string>

static OCTraceLogger * s_logger = NULL;
static const char * s_skip_image_names[] = {
    "WeChat",
    "demo",
    "IPAPatch",
    NULL,
};

static const char * s_skip_class_names[] = {
    "NewStrategyItem",
    "StrategyInterval",
    NULL,
};

static std::vector<OCTraceImage> s_image_list;

typedef id (*fn_objc_msgSend)(id self, SEL op);

static fn_objc_msgSend s_origin_objc_msgSend = NULL;

static bool __skip_image_addr(intptr_t addr) {
    bool retval = true;
    if (addr != (intptr_t)NULL) {
        for (std::vector<OCTraceImage>::iterator itor = s_image_list.begin();
             itor != s_image_list.end(); itor += 1) {
            OCTraceImage image = *itor;
            if (addr >= image.start_addr && addr <= image.end_addr) {
                retval = false;
                break;
            }
        }
    }
    return retval;
}

static bool __skip_class_name(const char * name) {
    bool retval = false;
    if (name != NULL) {
        for (int i = 0; s_skip_class_names[i] != NULL; i++) {
            if (strcasecmp(name, s_skip_class_names[i]) == 0) {
                retval = true;
            }
        }
    }
    return retval;
}

extern "C"
void * __hook_callback_pre(id self, SEL op, intptr_t arg0, intptr_t arg1) {
    const char* class_name = (char*) object_getClassName( self );
    Class clazz = objc_lookUpClass(class_name);

    if (!__skip_image_addr((intptr_t)clazz) && !__skip_class_name(class_name)) {
#if 0
        const char* op_name = (const char*) op;
        op_name = !op_name ? "null" : op_name;

        __uint64_t threadId = 0;
        if (pthread_threadid_np(0, &threadId)) {
            threadId = pthread_mach_thread_np(pthread_self());
        }

        fprintf(stderr, "[%ld:%llu] [%s %s] -> \n", (long)getpid(), threadId, class_name, op_name);
#endif
        if (s_logger) {
            s_logger->logBeforeCallee((intptr_t)self, (intptr_t)op);
        }
    }
    return (void *)s_origin_objc_msgSend;
}

extern "C"
void  __hook_callback_post(id self, SEL op) {
//    fprintf(stderr, "post self :%p, op:%s\n", self, (const char *)op);
    if (s_logger) {
        s_logger->logAfterCallee((intptr_t)self, (intptr_t)op);
    }
    return;
}

#if  __LP64__
__attribute__((naked))
static id new_objc_msgSend(id self, SEL op) {

    __asm__
    __volatile__ (
                  "stp fp, lr, [sp, #-16]!;\n"
                  "mov fp, sp;\n"

                  // store x10-x13,
                  "sub    sp, sp, #(8*16+14*8);\n"
                  "stp    x0, x1, [sp, #(0*8)];\n"
                  "stp    x2, x3, [sp, #(2*8)];\n"
                  "stp    x4, x5, [sp, #(4*8)];\n"
                  "stp    x6, x7, [sp, #(6*8)];\n"
                  "stp    x8, x9, [sp, #(8*8)];\n"
                  "stp    x10, x11, [sp, #(10*8)];\n"
                  "stp    x12, x13, [sp, #(12*8)];\n"
                  "stp    q0, q1, [sp, #(14*8+0*16)];\n"
                  "stp    q2, q3, [sp, #(14*8+2*16)];\n"
                  "stp    q4, q5, [sp, #(14*8+4*16)];\n"
                  "stp    q6, q7, [sp, #(14*8+6*16)];\n"

                  "ldr x9, [fp];\n"
                  "add x10, fp, #16;\n"

                  "adr lr, Llocal_return;\n"
                  "stp fp, lr, [sp, #-16]!;\n"
                  "mov fp, sp;\n"

                  // reconstruct arguments stack
                  "mov x11, x9;\n"
                  "mov x12, sp;\n"
                  "cmp x10, x11;\n"
                  "bhs Lskip_copy;\n"
                  "Lcopy_stack:\n"
                  "ldr x13, [x11,#-8]!;\n"
                  "str x13, [x12,#-8]!;\n"
                  "cmp x10, x11;\n"
                  "bne Lcopy_stack;\n"
                  "mov sp, x12;\n"
                  "Lskip_copy:\n"

                  "adr lr, Llocal_return;\n"

                  "BL ___hook_callback_pre;\n"
                  "mov x9, x0;\n"

                  "add    x10, fp, #16;\n"
                  "ldp    x0, x1, [x10, #(0*8)];\n"
                  "ldp    x2, x3, [x10, #(2*8)];\n"
                  "ldp    x4, x5, [x10, #(4*8)];\n"
                  "ldp    x6, x7, [x10, #(6*8)];\n"
                  "ldr    x8,     [x10, #(8*8)];\n"
                  "ldp    q0, q1, [x10, #(14*8+0*16)];\n"
                  "ldp    q2, q3, [x10, #(14*8+2*16)];\n"
                  "ldp    q4, q5, [x10, #(14*8+4*16)];\n"
                  "ldp    q6, q7, [x10, #(14*8+6*16)];\n"

                  "BLR    x9;\n"
                  "Llocal_return:\n"

                  // store x0-x8 / q0-q7 after call objc_sendMsg.
                  "add    x9, fp, #16;\n"
                  "ldp    x10, x11, [x9, #(0*8)];\n"
                  "stp    x0, x1, [x9, #(0*8)];\n"
                  "stp    x2, x3, [x9, #(2*8)];\n"
                  "stp    x4, x5, [x9, #(4*8)];\n"
                  "stp    x6, x7, [x9, #(6*8)];\n"
                  "str    x8,     [x9, #(8*8)];\n"
                  "stp    q0, q1, [x9, #(14*8+0*16)];\n"
                  "stp    q2, q3, [x9, #(14*8+2*16)];\n"
                  "stp    q4, q5, [x9, #(14*8+4*16)];\n"
                  "stp    q6, q7, [x9, #(14*8+6*16)];\n"

                  // restore self and op before call __hook_callback_post
                  "mov    x0, x10;\n"
                  "mov    x1, x11;\n"
                  "BL ___hook_callback_post;\n"

                  "mov    sp, fp;\n"
                  "ldp    fp, lr, [sp], #16;\n"

                  // restore x0-x13 and q0-q7 to objc_sendMsg's return values
                  "ldp    x0, x1, [sp, #(0*8)];\n"
                  "ldp    x2, x3, [sp, #(2*8)];\n"
                  "ldp    x4, x5, [sp, #(4*8)];\n"
                  "ldp    x6, x7, [sp, #(6*8)];\n"
                  "ldp    x8, x9, [sp, #(8*8)];\n"
                  "ldp    x10, x11, [sp, #(10*8)];\n"
                  "ldp    x12, x13, [sp, #(12*8)];\n"
                  "ldp    q0, q1, [sp, #(14*8+0*16)];\n"
                  "ldp    q2, q3, [sp, #(14*8+2*16)];\n"
                  "ldp    q4, q5, [sp, #(14*8+4*16)];\n"
                  "ldp    q6, q7, [sp, #(14*8+6*16)];\n"

                  "mov    sp, fp;\n"
                  "ldp    fp, lr, [sp], #16;\n"
                  "ret;\n"
                  );
}

#else

__attribute__((naked))
static id new_objc_msgSend(id self, SEL op) {

}

#endif

int OCTraceInit(OCTraceLogger * logger) {

#if 1
    OCTraceImageListInit();
    s_image_list.clear();
    for(int i = 0; s_skip_image_names[i] != NULL; i++) {
        const char * image_name = s_skip_image_names[i];
        OCTraceImage image = OCTraceGetImageWithName(image_name);
        if (image.start_addr != (intptr_t)NULL) {
            s_image_list.insert(s_image_list.end(), image);
        }
    }

#endif
    //s_logger = new OCTraceLocalLogger();
    s_logger = logger ;//new OCTraceRemoteLogger();

    s_origin_objc_msgSend = (fn_objc_msgSend)dlsym(RTLD_DEFAULT, "objc_msgSend");
    return rebind_symbols((struct rebinding[1]){{"objc_msgSend", (void *)new_objc_msgSend}}, 1);

}

<commit_msg>use imp addr to check image<commit_after>//
//  OCTrace.cpp
//  IPAPatch
//
//  Created by wadahana on 01/06/2017.
//  Copyright © 2017. All rights reserved.
//

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <dlfcn.h>
#include <assert.h>
#include <string.h>
#include <pthread.h>
#include <uuid/uuid.h>

#include <objc/objc.h>
#include <objc/runtime.h>
#include <mach/mach.h>
#include <mach-o/dyld_images.h>
#include <mach/vm_map.h>
#include <mach-o/loader.h>
#include <mach-o/nlist.h>
#include <mach-o/fat.h>
#include <mach-o/loader.h>
#include <mach-o/dyld.h>

#import "fishhook.h"

#include "OCTrace.h"
#include "OCTraceImage.h"
#include "OCTraceLogger.h"
#include "OCTraceLocalLogger.h"
#include "OCTraceRemoteLogger.h"
#include <vector>
#include <string>

static OCTraceLogger * s_logger = NULL;
static const char * s_skip_image_names[] = {
    "WeChat",
    "demo",
    "IPAPatch",
    NULL,
};

static const char * s_skip_class_names[] = {
    "NewStrategyItem",
    "StrategyInterval",
    NULL,
};

static std::vector<OCTraceImage> s_image_list;

typedef id (*fn_objc_msgSend)(id self, SEL op);

static fn_objc_msgSend s_origin_objc_msgSend = NULL;

static bool __skip_image_addr(intptr_t addr) {
    bool retval = true;
    if (addr != (intptr_t)NULL) {
        for (std::vector<OCTraceImage>::iterator itor = s_image_list.begin();
             itor != s_image_list.end(); itor += 1) {
            OCTraceImage image = *itor;
            if (addr >= image.start_addr && addr <= image.end_addr) {
                retval = false;
                break;
            }
        }
    }
    return retval;
}

static bool __skip_class_name(const char * name) {
    bool retval = false;
    if (name != NULL) {
        for (int i = 0; s_skip_class_names[i] != NULL; i++) {
            if (strcasecmp(name, s_skip_class_names[i]) == 0) {
                retval = true;
            }
        }
    }
    return retval;
}

extern "C"
void * __hook_callback_pre(id self, SEL op, intptr_t arg0, intptr_t arg1) {
    const char* class_name = (char*) object_getClassName( self );
    Class clazz = objc_lookUpClass(class_name);
    IMP imp = method_getImplementation(class_getInstanceMethod(clazz, op));
    if (!imp) {
        imp = method_getImplementation(class_getClassMethod(clazz, op));
    }

    if (!__skip_image_addr((intptr_t)imp) && !__skip_class_name(class_name)) {
#if 0
        const char* op_name = (const char*) op;
        op_name = !op_name ? "null" : op_name;

        __uint64_t threadId = 0;
        if (pthread_threadid_np(0, &threadId)) {
            threadId = pthread_mach_thread_np(pthread_self());
        }

        fprintf(stderr, "[%ld:%llu] [%s %s] -> \n", (long)getpid(), threadId, class_name, op_name);
#endif
        if (s_logger) {
            s_logger->logBeforeCallee((intptr_t)self, (intptr_t)op);
        }
    }
    return (void *)s_origin_objc_msgSend;
}

extern "C"
void  __hook_callback_post(id self, SEL op) {
//    fprintf(stderr, "post self :%p, op:%s\n", self, (const char *)op);
    if (s_logger) {
        s_logger->logAfterCallee((intptr_t)self, (intptr_t)op);
    }
    return;
}

#if  __LP64__
__attribute__((naked))
static id new_objc_msgSend(id self, SEL op) {

    __asm__
    __volatile__ (
                  "stp fp, lr, [sp, #-16]!;\n"
                  "mov fp, sp;\n"

                  // store x10-x13,
                  "sub    sp, sp, #(8*16+14*8);\n"
                  "stp    x0, x1, [sp, #(0*8)];\n"
                  "stp    x2, x3, [sp, #(2*8)];\n"
                  "stp    x4, x5, [sp, #(4*8)];\n"
                  "stp    x6, x7, [sp, #(6*8)];\n"
                  "stp    x8, x9, [sp, #(8*8)];\n"
                  "stp    x10, x11, [sp, #(10*8)];\n"
                  "stp    x12, x13, [sp, #(12*8)];\n"
                  "stp    q0, q1, [sp, #(14*8+0*16)];\n"
                  "stp    q2, q3, [sp, #(14*8+2*16)];\n"
                  "stp    q4, q5, [sp, #(14*8+4*16)];\n"
                  "stp    q6, q7, [sp, #(14*8+6*16)];\n"

                  "ldr x9, [fp];\n"
                  "add x10, fp, #16;\n"

                  "adr lr, Llocal_return;\n"
                  "stp fp, lr, [sp, #-16]!;\n"
                  "mov fp, sp;\n"

                  // reconstruct arguments stack
                  "mov x11, x9;\n"
                  "mov x12, sp;\n"
                  "cmp x10, x11;\n"
                  "bhs Lskip_copy;\n"
                  "Lcopy_stack:\n"
                  "ldr x13, [x11,#-8]!;\n"
                  "str x13, [x12,#-8]!;\n"
                  "cmp x10, x11;\n"
                  "bne Lcopy_stack;\n"
                  "mov sp, x12;\n"
                  "Lskip_copy:\n"

                  "adr lr, Llocal_return;\n"

                  "BL ___hook_callback_pre;\n"
                  "mov x9, x0;\n"

                  "add    x10, fp, #16;\n"
                  "ldp    x0, x1, [x10, #(0*8)];\n"
                  "ldp    x2, x3, [x10, #(2*8)];\n"
                  "ldp    x4, x5, [x10, #(4*8)];\n"
                  "ldp    x6, x7, [x10, #(6*8)];\n"
                  "ldr    x8,     [x10, #(8*8)];\n"
                  "ldp    q0, q1, [x10, #(14*8+0*16)];\n"
                  "ldp    q2, q3, [x10, #(14*8+2*16)];\n"
                  "ldp    q4, q5, [x10, #(14*8+4*16)];\n"
                  "ldp    q6, q7, [x10, #(14*8+6*16)];\n"

                  "BLR    x9;\n"
                  "Llocal_return:\n"

                  // store x0-x8 / q0-q7 after call objc_sendMsg.
                  "add    x9, fp, #16;\n"
                  "ldp    x10, x11, [x9, #(0*8)];\n"
                  "stp    x0, x1, [x9, #(0*8)];\n"
                  "stp    x2, x3, [x9, #(2*8)];\n"
                  "stp    x4, x5, [x9, #(4*8)];\n"
                  "stp    x6, x7, [x9, #(6*8)];\n"
                  "str    x8,     [x9, #(8*8)];\n"
                  "stp    q0, q1, [x9, #(14*8+0*16)];\n"
                  "stp    q2, q3, [x9, #(14*8+2*16)];\n"
                  "stp    q4, q5, [x9, #(14*8+4*16)];\n"
                  "stp    q6, q7, [x9, #(14*8+6*16)];\n"

                  // restore self and op before call __hook_callback_post
                  "mov    x0, x10;\n"
                  "mov    x1, x11;\n"
                  "BL ___hook_callback_post;\n"

                  "mov    sp, fp;\n"
                  "ldp    fp, lr, [sp], #16;\n"

                  // restore x0-x13 and q0-q7 to objc_sendMsg's return values
                  "ldp    x0, x1, [sp, #(0*8)];\n"
                  "ldp    x2, x3, [sp, #(2*8)];\n"
                  "ldp    x4, x5, [sp, #(4*8)];\n"
                  "ldp    x6, x7, [sp, #(6*8)];\n"
                  "ldp    x8, x9, [sp, #(8*8)];\n"
                  "ldp    x10, x11, [sp, #(10*8)];\n"
                  "ldp    x12, x13, [sp, #(12*8)];\n"
                  "ldp    q0, q1, [sp, #(14*8+0*16)];\n"
                  "ldp    q2, q3, [sp, #(14*8+2*16)];\n"
                  "ldp    q4, q5, [sp, #(14*8+4*16)];\n"
                  "ldp    q6, q7, [sp, #(14*8+6*16)];\n"

                  "mov    sp, fp;\n"
                  "ldp    fp, lr, [sp], #16;\n"
                  "ret;\n"
                  );
}

#else

__attribute__((naked))
static id new_objc_msgSend(id self, SEL op) {

}

#endif

int OCTraceInit(OCTraceLogger * logger) {

#if 1
    OCTraceImageListInit();
    s_image_list.clear();
    for(int i = 0; s_skip_image_names[i] != NULL; i++) {
        const char * image_name = s_skip_image_names[i];
        OCTraceImage image = OCTraceGetImageWithName(image_name);
        if (image.start_addr != (intptr_t)NULL) {
            s_image_list.insert(s_image_list.end(), image);
        }
    }

#endif
    s_logger = new OCTraceLocalLogger();
    //s_logger = logger ;//new OCTraceRemoteLogger();

    s_origin_objc_msgSend = (fn_objc_msgSend)dlsym(RTLD_DEFAULT, "objc_msgSend");
    return rebind_symbols((struct rebinding[1]){{"objc_msgSend", (void *)new_objc_msgSend}}, 1);

}

<|endoftext|>


<commit_before>//----------------------------------------------------------------------------
//
// "Copyright Centre National d'Etudes Spatiales"
//
// License:  LGPL
//
// See LICENSE.txt file in the top level directory for more details.
//
//----------------------------------------------------------------------------
// $Id$

#include <otb/HermiteInterpolator.h>

#include <string>
#include <cassert>

namespace ossimplugins
{

HermiteInterpolator::HermiteInterpolator():
  theNPointsAvailable(0),
  theXValues(NULL),
  theYValues(NULL),
  thedYValues(NULL),
  prodC(NULL),
  sumC(NULL),
  isComputed(false)
{
}

HermiteInterpolator::HermiteInterpolator(int nbrPoints, double* x, double* y, double* dy):
  theNPointsAvailable(nbrPoints),
  isComputed(false)
{
  if(x != NULL)
  {
    theXValues = new double[theNPointsAvailable];
    for (int i=0;i<theNPointsAvailable;i++)
    {
      theXValues[i] = x[i];
    }
  }
  else
  {
    theXValues = NULL;
  }

  if(y != NULL)
  {
    theYValues = new double[theNPointsAvailable];
    for (int i=0;i<theNPointsAvailable;i++)
    {
      theYValues[i] = y[i];
    }
  }
  else
  {
    theYValues = NULL;
  }

  if(dy != NULL)
  {
    thedYValues = new double[theNPointsAvailable];
    for (int i=0;i<theNPointsAvailable;i++)
    {
      thedYValues[i] = dy[i];
    }
  }
  else
  {
    thedYValues = NULL;
  }

  for (int i = 1 ; i < theNPointsAvailable ; i++)
  {
    /**
     * @todo Verifier que l'interpolateur n'ai pas besoin ques les abscisses soitent strictement croissantes
     */

    /*
     * Les abscisses ne sont pas croissantes
     */
//    if (theXValues[i] <= theXValues[i-1])
//      std::cerr << "WARNING: Hermite interpolation assumes increasing x values" << std::endl;
    assert(theXValues[i] > theXValues[i-1]);
  }
}

HermiteInterpolator::~HermiteInterpolator()
{
  Clear();
}

HermiteInterpolator::HermiteInterpolator(const HermiteInterpolator& rhs):
  theNPointsAvailable(rhs.theNPointsAvailable),
  isComputed(false)
{
  if(rhs.theXValues != NULL)
  {
    theXValues = new double[theNPointsAvailable];
    for (int i=0;i<theNPointsAvailable;i++)
    {
      theXValues[i] = rhs.theXValues[i];
    }
  }
  else
  {
    theXValues = NULL;
  }

  if(rhs.theYValues != NULL)
  {
    theYValues = new double[theNPointsAvailable];
    for (int i=0;i<theNPointsAvailable;i++)
    {
      theYValues[i] = rhs.theYValues[i];
    }
  }
  else
  {
    theYValues = NULL;
  }

  if(rhs.thedYValues != NULL)
  {
    thedYValues = new double[theNPointsAvailable];
    for (int i=0;i<theNPointsAvailable;i++)
    {
      thedYValues[i] = rhs.thedYValues[i];
    }
  }
  else
  {
    thedYValues = NULL;
  }
}

HermiteInterpolator& HermiteInterpolator::operator =(const HermiteInterpolator& rhs)
{
  Clear();
  theNPointsAvailable = rhs.theNPointsAvailable;
  isComputed = false;
  if(rhs.theXValues != NULL)
  {
    theXValues = new double[theNPointsAvailable];
    for (int i=0;i<theNPointsAvailable;i++)
    {
      theXValues[i] = rhs.theXValues[i];
    }
  }
  else
  {
    theXValues = NULL;
  }

  if(rhs.theYValues != NULL)
  {
    theYValues = new double[theNPointsAvailable];
    for (int i=0;i<theNPointsAvailable;i++)
    {
      theYValues[i] = rhs.theYValues[i];
    }
  }
  else
  {
    theYValues = NULL;
  }

  if(rhs.thedYValues != NULL)
  {
    thedYValues = new double[theNPointsAvailable];
    for (int i=0;i<theNPointsAvailable;i++)
    {
      thedYValues[i] = rhs.thedYValues[i];
    }
  }
  else
  {
    thedYValues = NULL;
  }

  return *this;
}

// Interpolation method for the value and the derivative
int HermiteInterpolator::Interpolate(double x, double& y, double& dy) const
{
  //NOTE assume that x is increasing

  // Not enough points to interpolate
  if (theNPointsAvailable < 2) return -1;

  y = 0.0;
  dy = 0.0;

  //Precompute useful value if they are not available
  if (!isComputed)
  {
    Precompute();
  }

  for (int i = 0; i < theNPointsAvailable; i++)
  {
    double si = 0.0;
    double hi = 1.0;
    double ui = 0; //derivative computation
    double r = x - theXValues[i];

    for (int j = 0; j < theNPointsAvailable; j++)
    {
      if (j != i)
      {
        hi = hi * (x - theXValues[j]);
        ui = ui + 1 / (x - theXValues[j]);//derivative computation
      }
    }
    hi *= prodC[i];
    si = sumC[i];

    double f = 1.0 - 2.0 * r * si;

    y += (theYValues[i] * f + thedYValues[i] * r) * hi * hi;

    ui *= hi;//derivative computation

    double fp = 2.0 * hi * (ui * (1.0 - 2.0 * si * r) - hi * si);//derivative computation
    double d = hi * (hi + 2.0 * r * ui);//derivative computation

    dy += fp * theYValues[i] + d * thedYValues[i];//derivative computation

  }

  return 0;
}

// Interpolation method for the value only
// this is about 5 times faster and should be used when time
// is a constraint.
int HermiteInterpolator::Interpolate(double x, double& y) const
{
  //NOTE assume that x is increasing

  // Not enough points to interpolate
  if (theNPointsAvailable < 2) return -1;

  y = 0.0;

  //Precompute useful value if they are not available
  if (!isComputed)
  {
    Precompute();
  }

  for (int i = 0; i < theNPointsAvailable; i++)
  {
    double si = 0.0;
    double hi = 1.0;
    double r = x - theXValues[i];

    for (int j = 0; j < theNPointsAvailable; j++)
    {
      if (j != i)
      {
        hi = hi * (x - theXValues[j]);
      }
    }
    hi *= prodC[i];
    si = sumC[i];

    double f = 1.0 - 2.0 * r * si;

    y += (theYValues[i] * f + thedYValues[i] * r) * hi * hi;

  }

  return 0;
}

int HermiteInterpolator::Precompute() const
{
  prodC = new double[theNPointsAvailable];
  sumC= new double[theNPointsAvailable];

  for (int i = 0; i < theNPointsAvailable; i++)
  {
    prodC[i] = 1;
    sumC[i] = 0;
    for (int j = 0; j < theNPointsAvailable; j++)
    {
      if (j != i)
      {
        double v = 1.0 / (theXValues[i] - theXValues[j]);
        prodC[i] *= v;
        sumC[i]  += v;
      }
    }
  }
  isComputed = true;
}

void HermiteInterpolator::Clear()
{
  if (theXValues != NULL)
  {
    delete[] theXValues;
    theXValues = NULL;
  }

  if (theYValues != NULL)
  {
    delete[] theYValues;
    theYValues = NULL;
  }

  if (thedYValues != NULL)
  {
    delete[] thedYValues;
    thedYValues = NULL;
  }

  if (prodC != NULL)
  {
    delete[] prodC;
    prodC = NULL;
  }

  if (sumC != NULL)
  {
    delete[] sumC;
    prodC = NULL;
  }
  isComputed = false;
  theNPointsAvailable = 0;
}
}
<commit_msg>WRG: fix warning<commit_after>//----------------------------------------------------------------------------
//
// "Copyright Centre National d'Etudes Spatiales"
//
// License:  LGPL
//
// See LICENSE.txt file in the top level directory for more details.
//
//----------------------------------------------------------------------------
// $Id$

#include <otb/HermiteInterpolator.h>

#include <string>
#include <cassert>

namespace ossimplugins
{

HermiteInterpolator::HermiteInterpolator():
  theNPointsAvailable(0),
  theXValues(NULL),
  theYValues(NULL),
  thedYValues(NULL),
  prodC(NULL),
  sumC(NULL),
  isComputed(false)
{
}

HermiteInterpolator::HermiteInterpolator(int nbrPoints, double* x, double* y, double* dy):
  theNPointsAvailable(nbrPoints),
  isComputed(false)
{
  if(x != NULL)
  {
    theXValues = new double[theNPointsAvailable];
    for (int i=0;i<theNPointsAvailable;i++)
    {
      theXValues[i] = x[i];
    }
  }
  else
  {
    theXValues = NULL;
  }

  if(y != NULL)
  {
    theYValues = new double[theNPointsAvailable];
    for (int i=0;i<theNPointsAvailable;i++)
    {
      theYValues[i] = y[i];
    }
  }
  else
  {
    theYValues = NULL;
  }

  if(dy != NULL)
  {
    thedYValues = new double[theNPointsAvailable];
    for (int i=0;i<theNPointsAvailable;i++)
    {
      thedYValues[i] = dy[i];
    }
  }
  else
  {
    thedYValues = NULL;
  }

  for (int i = 1 ; i < theNPointsAvailable ; i++)
  {
    /**
     * @todo Verifier que l'interpolateur n'ai pas besoin ques les abscisses soitent strictement croissantes
     */

    /*
     * Les abscisses ne sont pas croissantes
     */
//    if (theXValues[i] <= theXValues[i-1])
//      std::cerr << "WARNING: Hermite interpolation assumes increasing x values" << std::endl;
    assert(theXValues[i] > theXValues[i-1]);
  }
}

HermiteInterpolator::~HermiteInterpolator()
{
  Clear();
}

HermiteInterpolator::HermiteInterpolator(const HermiteInterpolator& rhs):
  theNPointsAvailable(rhs.theNPointsAvailable),
  isComputed(false)
{
  if(rhs.theXValues != NULL)
  {
    theXValues = new double[theNPointsAvailable];
    for (int i=0;i<theNPointsAvailable;i++)
    {
      theXValues[i] = rhs.theXValues[i];
    }
  }
  else
  {
    theXValues = NULL;
  }

  if(rhs.theYValues != NULL)
  {
    theYValues = new double[theNPointsAvailable];
    for (int i=0;i<theNPointsAvailable;i++)
    {
      theYValues[i] = rhs.theYValues[i];
    }
  }
  else
  {
    theYValues = NULL;
  }

  if(rhs.thedYValues != NULL)
  {
    thedYValues = new double[theNPointsAvailable];
    for (int i=0;i<theNPointsAvailable;i++)
    {
      thedYValues[i] = rhs.thedYValues[i];
    }
  }
  else
  {
    thedYValues = NULL;
  }
}

HermiteInterpolator& HermiteInterpolator::operator =(const HermiteInterpolator& rhs)
{
  Clear();
  theNPointsAvailable = rhs.theNPointsAvailable;
  isComputed = false;
  if(rhs.theXValues != NULL)
  {
    theXValues = new double[theNPointsAvailable];
    for (int i=0;i<theNPointsAvailable;i++)
    {
      theXValues[i] = rhs.theXValues[i];
    }
  }
  else
  {
    theXValues = NULL;
  }

  if(rhs.theYValues != NULL)
  {
    theYValues = new double[theNPointsAvailable];
    for (int i=0;i<theNPointsAvailable;i++)
    {
      theYValues[i] = rhs.theYValues[i];
    }
  }
  else
  {
    theYValues = NULL;
  }

  if(rhs.thedYValues != NULL)
  {
    thedYValues = new double[theNPointsAvailable];
    for (int i=0;i<theNPointsAvailable;i++)
    {
      thedYValues[i] = rhs.thedYValues[i];
    }
  }
  else
  {
    thedYValues = NULL;
  }

  return *this;
}

// Interpolation method for the value and the derivative
int HermiteInterpolator::Interpolate(double x, double& y, double& dy) const
{
  //NOTE assume that x is increasing

  // Not enough points to interpolate
  if (theNPointsAvailable < 2) return -1;

  y = 0.0;
  dy = 0.0;

  //Precompute useful value if they are not available
  if (!isComputed)
  {
    Precompute();
  }

  for (int i = 0; i < theNPointsAvailable; i++)
  {
    double si = 0.0;
    double hi = 1.0;
    double ui = 0; //derivative computation
    double r = x - theXValues[i];

    for (int j = 0; j < theNPointsAvailable; j++)
    {
      if (j != i)
      {
        hi = hi * (x - theXValues[j]);
        ui = ui + 1 / (x - theXValues[j]);//derivative computation
      }
    }
    hi *= prodC[i];
    si = sumC[i];

    double f = 1.0 - 2.0 * r * si;

    y += (theYValues[i] * f + thedYValues[i] * r) * hi * hi;

    ui *= hi;//derivative computation

    double fp = 2.0 * hi * (ui * (1.0 - 2.0 * si * r) - hi * si);//derivative computation
    double d = hi * (hi + 2.0 * r * ui);//derivative computation

    dy += fp * theYValues[i] + d * thedYValues[i];//derivative computation

  }

  return 0;
}

// Interpolation method for the value only
// this is about 5 times faster and should be used when time
// is a constraint.
int HermiteInterpolator::Interpolate(double x, double& y) const
{
  //NOTE assume that x is increasing

  // Not enough points to interpolate
  if (theNPointsAvailable < 2) return -1;

  y = 0.0;

  //Precompute useful value if they are not available
  if (!isComputed)
  {
    Precompute();
  }

  for (int i = 0; i < theNPointsAvailable; i++)
  {
    double si = 0.0;
    double hi = 1.0;
    double r = x - theXValues[i];

    for (int j = 0; j < theNPointsAvailable; j++)
    {
      if (j != i)
      {
        hi = hi * (x - theXValues[j]);
      }
    }
    hi *= prodC[i];
    si = sumC[i];

    double f = 1.0 - 2.0 * r * si;

    y += (theYValues[i] * f + thedYValues[i] * r) * hi * hi;

  }

  return 0;
}

int HermiteInterpolator::Precompute() const
{
  prodC = new double[theNPointsAvailable];
  sumC= new double[theNPointsAvailable];

  for (int i = 0; i < theNPointsAvailable; i++)
  {
    prodC[i] = 1;
    sumC[i] = 0;
    for (int j = 0; j < theNPointsAvailable; j++)
    {
      if (j != i)
      {
        double v = 1.0 / (theXValues[i] - theXValues[j]);
        prodC[i] *= v;
        sumC[i]  += v;
      }
    }
  }
  isComputed = true;
  return 0;
}

void HermiteInterpolator::Clear()
{
  if (theXValues != NULL)
  {
    delete[] theXValues;
    theXValues = NULL;
  }

  if (theYValues != NULL)
  {
    delete[] theYValues;
    theYValues = NULL;
  }

  if (thedYValues != NULL)
  {
    delete[] thedYValues;
    thedYValues = NULL;
  }

  if (prodC != NULL)
  {
    delete[] prodC;
    prodC = NULL;
  }

  if (sumC != NULL)
  {
    delete[] sumC;
    prodC = NULL;
  }
  isComputed = false;
  theNPointsAvailable = 0;
}
}
<|endoftext|>


<commit_before>#include <rclcpp/rclcpp.hpp>

#include <std_msgs/String.h>
#include "std_msgs/dds_impl/String_convert.h"

#include <std_msgs/Int32.h>
#include <rclcpp_examples/AddTwoIntsRequest.h>
#include <rclcpp_examples/AddTwoIntsResponse.h>

#include "std_msgs/dds_impl/Int32_convert.h"
#include "rclcpp_examples/dds_impl/AddTwoIntsRequest_convert.h"
#include "rclcpp_examples/dds_impl/AddTwoIntsResponse_convert.h"

#include <iostream>

int main(int argc, char** argv)
{
    rclcpp::init(argc, argv);

    rclcpp::Node::Ptr node = rclcpp::create_node("add_two_ints_server");
    auto client = node->create_client<rclcpp_examples::AddTwoIntsRequest, rclcpp_examples::AddTwoIntsResponse>("add_two_ints");
    rclcpp_examples::AddTwoIntsRequest req;
    req.a = 2;
    req.b = 3;

    auto response = client->async_call(req);
    //std::cout << "Sum: " << response->sum << std::endl;

    node->spin();
    return 0;
}
<commit_msg>Use sync call<commit_after>#include <rclcpp/rclcpp.hpp>

#include <std_msgs/String.h>
#include "std_msgs/dds_impl/String_convert.h"

#include <std_msgs/Int32.h>
#include <rclcpp_examples/AddTwoIntsRequest.h>
#include <rclcpp_examples/AddTwoIntsResponse.h>

#include "std_msgs/dds_impl/Int32_convert.h"
#include "rclcpp_examples/dds_impl/AddTwoIntsRequest_convert.h"
#include "rclcpp_examples/dds_impl/AddTwoIntsResponse_convert.h"

#include <iostream>

int main(int argc, char** argv)
{
    rclcpp::init(argc, argv);

    rclcpp::Node::Ptr node = rclcpp::create_node("add_two_ints_server");
    auto client = node->create_client<rclcpp_examples::AddTwoIntsRequest, rclcpp_examples::AddTwoIntsResponse>("add_two_ints");
    rclcpp_examples::AddTwoIntsRequest req;
    req.a = 2;
    req.b = 3;

    auto response = client->call(req);
    std::cout << "Sum: " << response->sum << std::endl;

    return 0;
}
<|endoftext|>


<commit_before>/**
  This file contains a sequence of tests to perform for different instances of a templatized fixture.
  It is thus inlined several times in the .cpp test file.
  */

// ==============================
// Set/get value tests
TEST_F(TestMatrix, set_fullMat ) { ASSERT_TRUE( matrixMaxDiff(mat,fullMat) < 100*epsilon() ); }
TEST_F(TestMatrix, set_crs1 ) { ASSERT_TRUE( matrixMaxDiff( fullMat,crs1 ) < 100*epsilon() ); }
TEST_F(TestMatrix, set_crs2 ) { ASSERT_TRUE( matrixMaxDiff(fullMat,crs2) < 100*epsilon() ); }
TEST_F(TestMatrix, set_mapMat ) { ASSERT_TRUE( matrixMaxDiff(fullMat,mapMat) < 100*epsilon() ); }
TEST_F(TestMatrix, set_eiBlock1 ) { ASSERT_TRUE( matrixMaxDiff(fullMat,eiBlock1) < 100*epsilon() ); }
TEST_F(TestMatrix, set_eiBlock2 ) { ASSERT_TRUE( matrixMaxDiff(fullMat,eiBlock2) < 100*epsilon() ); }
TEST_F(TestMatrix, set_eiBase ) { ASSERT_TRUE( matrixMaxDiff(fullMat,eiBase) < 100*epsilon() ); }
TEST_F(TestMatrix, eigenMatrix_update ) { ASSERT_TRUE( checkEigenMatrixUpdate() ); }
TEST_F(TestMatrix, eigenMatrix_block_row_filling ) { ASSERT_TRUE( checkEigenMatrixBlockRowFilling() ); }
TEST_F(TestMatrix, eigenMatrixBlockFromCompressedRowSparseMatrix ) { ASSERT_TRUE( checkEigenMatrixBlockFromCompressedRowSparseMatrix() ); }
TEST_F(TestMatrix, eigenMapToDenseMatrix ) { ASSERT_TRUE( checkEigenDenseMatrix() ); }

// ==============================
// Matrix-Vector product tests
TEST_F(TestMatrix, set_fullVec_nrows_reference )
{
    ASSERT_TRUE(vectorMaxDiff(vecM,fullVec_nrows_reference) < epsilon() );
}
TEST_F(TestMatrix, fullMat_vector_product )
{
//    fullMat.opMulV(&fullVec_nrows_result,&fullVec_ncols);
    fullVec_nrows_result = fullMat * fullVec_ncols;
    ASSERT_TRUE(vectorMaxDiff(fullVec_nrows_reference,fullVec_nrows_result) < epsilon() );
}
TEST_F(TestMatrix, mapMat_vector_product )
{
//    mapMat.opMulV(&fullVec_nrows_result,&fullVec_ncols);
    fullVec_nrows_result = mapMat * fullVec_ncols;
    ASSERT_TRUE(vectorMaxDiff(fullVec_nrows_reference,fullVec_nrows_result) < epsilon() );
}
TEST_F(TestMatrix, eiBlock1_vector_product )
{
//    eiBlock1.opMulV(&fullVec_nrows_result,&fullVec_ncols);
//    eiBlock1.multVector(fullVec_nrows_result,fullVec_ncols);
    fullVec_nrows_result = eiBlock1 * fullVec_ncols;
    ASSERT_TRUE(vectorMaxDiff(fullVec_nrows_reference,fullVec_nrows_result) < epsilon() );

}
TEST_F(TestMatrix, crs1_vector_product )
{
//    EXPECT_TRUE(NROWS%BROWS==0 && NCOLS%BCOLS==0) << "Error: CompressedRowSparseMatrix * Vector crashes when the size of the matrix is not a multiple of the size of the matrix blocks. Aborting this test, and reporting a failure."; // otherwise the product crashes
//    crs1.opMulV(&fullVec_nrows_result,&fullVec_ncols);
    fullVec_nrows_result = crs1 * fullVec_ncols;
    ASSERT_TRUE(vectorMaxDiff(fullVec_nrows_reference,fullVec_nrows_result) < epsilon() );
}

// ==============================
// Matrix product tests
TEST_F(TestMatrix, full_matrix_product ) { ASSERT_TRUE( matrixMaxDiff(matMultiplication,fullMultiplication) < 100*epsilon() );  }
TEST_F(TestMatrix, crs_matrix_product ) { ASSERT_TRUE( matrixMaxDiff(fullMultiplication,crsMultiplication) < 100*epsilon() ); }
TEST_F(TestMatrix, EigenBase_matrix_product ) { ASSERT_TRUE( matrixMaxDiff(fullMultiplication,eiBaseMultiplication) < 100*epsilon() ); }
TEST_F(TestMatrix, EigenSparseDense_matrix_product ) { ASSERT_TRUE( EigenDenseMatrix(eiBaseMultiplication.compressedMatrix) == eiDenseMultiplication ); }
TEST_F(TestMatrix, full_matrix_transposeproduct ) { ASSERT_TRUE( matrixMaxDiff(matTransposeMultiplication,fullTransposeMultiplication) < 100*epsilon() ); }
TEST_F(TestMatrix, crs_matrix_transposeproduct ) { ASSERT_TRUE( matrixMaxDiff(fullTransposeMultiplication,crsTransposeMultiplication) < 100*epsilon() ); }

// Matrix addition
TEST_F(TestMatrix, crs_matrix_addition )
{
    crs2 = crs1 + crs1;
    ASSERT_TRUE( matrixMaxDiff(mat*2,crs2) < 100*epsilon() );

    crs2 += crs1;
    ASSERT_TRUE( matrixMaxDiff(mat*3,crs2) < 100*epsilon() );

    crs2 -= crs1;
    ASSERT_FALSE( matrixMaxDiff(mat*2,crs2) < 100*epsilon() ); // create an error to check if I get a message from Jenkins
    //    ASSERT_TRUE( matrixMaxDiff(mat*2,crs2) < 100*epsilon() );
}
<commit_msg>META-TEST adding a failure<commit_after>/**
  This file contains a sequence of tests to perform for different instances of a templatized fixture.
  It is thus inlined several times in the .cpp test file.
  */

// ==============================
// Set/get value tests
TEST_F(TestMatrix, set_fullMat ) { ASSERT_TRUE( matrixMaxDiff(mat,fullMat) < 100*epsilon() ); }
TEST_F(TestMatrix, set_crs1 ) { ASSERT_TRUE( matrixMaxDiff( fullMat,crs1 ) < 100*epsilon() ); }
TEST_F(TestMatrix, set_crs2 ) { ASSERT_TRUE( matrixMaxDiff(fullMat,crs2) < 100*epsilon() ); }
TEST_F(TestMatrix, set_mapMat ) { ASSERT_TRUE( matrixMaxDiff(fullMat,mapMat) < 100*epsilon() ); }
TEST_F(TestMatrix, set_eiBlock1 ) { ASSERT_TRUE( matrixMaxDiff(fullMat,eiBlock1) < 100*epsilon() ); }
TEST_F(TestMatrix, set_eiBlock2 ) { ASSERT_TRUE( matrixMaxDiff(fullMat,eiBlock2) < 100*epsilon() ); }
TEST_F(TestMatrix, set_eiBase ) { ASSERT_TRUE( matrixMaxDiff(fullMat,eiBase) < 100*epsilon() ); }
TEST_F(TestMatrix, eigenMatrix_update ) { ASSERT_TRUE( checkEigenMatrixUpdate() ); }
TEST_F(TestMatrix, eigenMatrix_block_row_filling ) { ASSERT_TRUE( checkEigenMatrixBlockRowFilling() ); }
TEST_F(TestMatrix, eigenMatrixBlockFromCompressedRowSparseMatrix ) { ASSERT_TRUE( checkEigenMatrixBlockFromCompressedRowSparseMatrix() ); }
TEST_F(TestMatrix, eigenMapToDenseMatrix ) { ASSERT_TRUE( checkEigenDenseMatrix() ); }

// ==============================
// Matrix-Vector product tests
TEST_F(TestMatrix, set_fullVec_nrows_reference )
{
    ASSERT_TRUE(vectorMaxDiff(vecM,fullVec_nrows_reference) < epsilon() );
}
TEST_F(TestMatrix, fullMat_vector_product )
{
//    fullMat.opMulV(&fullVec_nrows_result,&fullVec_ncols);
    fullVec_nrows_result = fullMat * fullVec_ncols;
    ASSERT_TRUE(vectorMaxDiff(fullVec_nrows_reference,fullVec_nrows_result) < epsilon() );
}
TEST_F(TestMatrix, mapMat_vector_product )
{
//    mapMat.opMulV(&fullVec_nrows_result,&fullVec_ncols);
    fullVec_nrows_result = mapMat * fullVec_ncols;
    ASSERT_TRUE(vectorMaxDiff(fullVec_nrows_reference,fullVec_nrows_result) < epsilon() );
}
TEST_F(TestMatrix, eiBlock1_vector_product )
{
//    eiBlock1.opMulV(&fullVec_nrows_result,&fullVec_ncols);
//    eiBlock1.multVector(fullVec_nrows_result,fullVec_ncols);
    fullVec_nrows_result = eiBlock1 * fullVec_ncols;
    ASSERT_TRUE(vectorMaxDiff(fullVec_nrows_reference,fullVec_nrows_result) < epsilon() );

}
TEST_F(TestMatrix, crs1_vector_product )
{
//    EXPECT_TRUE(NROWS%BROWS==0 && NCOLS%BCOLS==0) << "Error: CompressedRowSparseMatrix * Vector crashes when the size of the matrix is not a multiple of the size of the matrix blocks. Aborting this test, and reporting a failure."; // otherwise the product crashes
//    crs1.opMulV(&fullVec_nrows_result,&fullVec_ncols);
    fullVec_nrows_result = crs1 * fullVec_ncols;
    ASSERT_FALSE(vectorMaxDiff(fullVec_nrows_reference,fullVec_nrows_result) < epsilon() ); // create an error to check if I get a message from Jenkins
//    ASSERT_TRUE(vectorMaxDiff(fullVec_nrows_reference,fullVec_nrows_result) < epsilon() );
}

// ==============================
// Matrix product tests
TEST_F(TestMatrix, full_matrix_product ) { ASSERT_TRUE( matrixMaxDiff(matMultiplication,fullMultiplication) < 100*epsilon() );  }
TEST_F(TestMatrix, crs_matrix_product ) { ASSERT_TRUE( matrixMaxDiff(fullMultiplication,crsMultiplication) < 100*epsilon() ); }
TEST_F(TestMatrix, EigenBase_matrix_product ) { ASSERT_TRUE( matrixMaxDiff(fullMultiplication,eiBaseMultiplication) < 100*epsilon() ); }
TEST_F(TestMatrix, EigenSparseDense_matrix_product ) { ASSERT_TRUE( EigenDenseMatrix(eiBaseMultiplication.compressedMatrix) == eiDenseMultiplication ); }
TEST_F(TestMatrix, full_matrix_transposeproduct ) { ASSERT_TRUE( matrixMaxDiff(matTransposeMultiplication,fullTransposeMultiplication) < 100*epsilon() ); }
TEST_F(TestMatrix, crs_matrix_transposeproduct ) { ASSERT_TRUE( matrixMaxDiff(fullTransposeMultiplication,crsTransposeMultiplication) < 100*epsilon() ); }

// Matrix addition
TEST_F(TestMatrix, crs_matrix_addition )
{
    crs2 = crs1 + crs1;
    ASSERT_TRUE( matrixMaxDiff(mat*2,crs2) < 100*epsilon() );

    crs2 += crs1;
    ASSERT_TRUE( matrixMaxDiff(mat*3,crs2) < 100*epsilon() );

    crs2 -= crs1;
    ASSERT_FALSE( matrixMaxDiff(mat*2,crs2) < 100*epsilon() ); // create an error to check if I get a message from Jenkins
    //    ASSERT_TRUE( matrixMaxDiff(mat*2,crs2) < 100*epsilon() );
}
<|endoftext|>


<commit_before>//===-- SymbolVendorMacOSX.cpp ----------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "SymbolVendorMacOSX.h"

#include <string.h>

#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Host/XML.h"
#include "lldb/Symbol/ObjectFile.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// SymbolVendorMacOSX constructor
//----------------------------------------------------------------------
SymbolVendorMacOSX::SymbolVendorMacOSX(const lldb::ModuleSP &module_sp) :
    SymbolVendor (module_sp)
{
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
SymbolVendorMacOSX::~SymbolVendorMacOSX()
{
}

static bool
UUIDsMatch(Module *module, ObjectFile *ofile, lldb_private::Stream *feedback_strm)
{
    if (module && ofile)
    {
        // Make sure the UUIDs match
        lldb_private::UUID dsym_uuid;

        if (!ofile->GetUUID(&dsym_uuid))
        {
            if (feedback_strm)
            {
                feedback_strm->PutCString("warning: failed to get the uuid for object file: '");
                ofile->GetFileSpec().Dump(feedback_strm);
                feedback_strm->PutCString("\n");
            }
            return false;
        }

        if (dsym_uuid == module->GetUUID())
            return true;

        // Emit some warning messages since the UUIDs do not match!
        if (feedback_strm)
        {
            feedback_strm->PutCString("warning: UUID mismatch detected between modules:\n    ");
            module->GetUUID().Dump(feedback_strm);
            feedback_strm->PutChar(' ');
            module->GetFileSpec().Dump(feedback_strm);
            feedback_strm->PutCString("\n    ");
            dsym_uuid.Dump(feedback_strm);
            feedback_strm->PutChar(' ');
            ofile->GetFileSpec().Dump(feedback_strm);
            feedback_strm->EOL();
        }
    }
    return false;
}

void
SymbolVendorMacOSX::Initialize()
{
    PluginManager::RegisterPlugin (GetPluginNameStatic(),
                                   GetPluginDescriptionStatic(),
                                   CreateInstance);
}

void
SymbolVendorMacOSX::Terminate()
{
    PluginManager::UnregisterPlugin (CreateInstance);
}

lldb_private::ConstString
SymbolVendorMacOSX::GetPluginNameStatic()
{
    static ConstString g_name("macosx");
    return g_name;
}

const char *
SymbolVendorMacOSX::GetPluginDescriptionStatic()
{
    return "Symbol vendor for MacOSX that looks for dSYM files that match executables.";
}

//----------------------------------------------------------------------
// CreateInstance
//
// Platforms can register a callback to use when creating symbol
// vendors to allow for complex debug information file setups, and to
// also allow for finding separate debug information files.
//----------------------------------------------------------------------
SymbolVendor*
SymbolVendorMacOSX::CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm)
{
    if (!module_sp)
        return NULL;

    ObjectFile * obj_file = module_sp->GetObjectFile();
    if (!obj_file)
        return NULL;

    static ConstString obj_file_macho("mach-o");
    ConstString obj_name = obj_file->GetPluginName();
    if (obj_name != obj_file_macho)
        return NULL;

    Timer scoped_timer (__PRETTY_FUNCTION__,
                        "SymbolVendorMacOSX::CreateInstance (module = %s)",
                        module_sp->GetFileSpec().GetPath().c_str());
    SymbolVendorMacOSX* symbol_vendor = new SymbolVendorMacOSX(module_sp);
    if (symbol_vendor)
    {
        char path[PATH_MAX];
        path[0] = '\0';

        // Try and locate the dSYM file on Mac OS X
        Timer scoped_timer2 ("SymbolVendorMacOSX::CreateInstance () locate dSYM",
                             "SymbolVendorMacOSX::CreateInstance (module = %s) locate dSYM",
                             module_sp->GetFileSpec().GetPath().c_str());

        // First check to see if the module has a symbol file in mind already.
        // If it does, then we MUST use that.
        FileSpec dsym_fspec (module_sp->GetSymbolFileFileSpec());

        ObjectFileSP dsym_objfile_sp;
        if (!dsym_fspec)
        {
            // No symbol file was specified in the module, lets try and find
            // one ourselves.
            FileSpec file_spec = obj_file->GetFileSpec();
            if (!file_spec)
                file_spec = module_sp->GetFileSpec();

            ModuleSpec module_spec(file_spec, module_sp->GetArchitecture());
            module_spec.GetUUID() = module_sp->GetUUID();
            dsym_fspec = Symbols::LocateExecutableSymbolFile (module_spec);
            if (module_spec.GetSourceMappingList().GetSize())
                module_sp->GetSourceMappingList().Append (module_spec.GetSourceMappingList (), true);
        }

        if (dsym_fspec)
        {
            DataBufferSP dsym_file_data_sp;
            lldb::offset_t dsym_file_data_offset = 0;
            dsym_objfile_sp = ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(), dsym_file_data_sp, dsym_file_data_offset);
            if (UUIDsMatch(module_sp.get(), dsym_objfile_sp.get(), feedback_strm))
            {
                // We need a XML parser if we hope to parse a plist...
                if (XMLDocument::XMLEnabled())
                {
                    char dsym_path[PATH_MAX];
                    if (module_sp->GetSourceMappingList().IsEmpty() && dsym_fspec.GetPath(dsym_path, sizeof(dsym_path)))
                    {
                        lldb_private::UUID dsym_uuid;
                        if (dsym_objfile_sp->GetUUID(&dsym_uuid))
                        {
                            std::string uuid_str = dsym_uuid.GetAsString ();
                            if (!uuid_str.empty())
                            {
                                char *resources = strstr (dsym_path, "/Contents/Resources/");
                                if (resources)
                                {
                                    char dsym_uuid_plist_path[PATH_MAX];
                                    resources[strlen("/Contents/Resources/")] = '\0';
                                    snprintf(dsym_uuid_plist_path, sizeof(dsym_uuid_plist_path), "%s%s.plist", dsym_path, uuid_str.c_str());
                                    FileSpec dsym_uuid_plist_spec(dsym_uuid_plist_path, false);
                                    if (dsym_uuid_plist_spec.Exists())
                                    {
                                        ApplePropertyList plist(dsym_uuid_plist_path);
                                        if (plist)
                                        {
                                            std::string DBGBuildSourcePath;
                                            std::string DBGSourcePath;

                                            plist.GetValueAsString("DBGBuildSourcePath", DBGBuildSourcePath);
                                            plist.GetValueAsString("DBGSourcePath", DBGSourcePath);
                                            if (DBGBuildSourcePath[0] && DBGSourcePath[0])
                                            {
                                                module_sp->GetSourceMappingList().Append (ConstString(DBGBuildSourcePath), ConstString(DBGSourcePath), true);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
                return symbol_vendor;
            }
        }

        // Just create our symbol vendor using the current objfile as this is either
        // an executable with no dSYM (that we could locate), an executable with
        // a dSYM that has a UUID that doesn't match.
        symbol_vendor->AddSymbolFileRepresentation(obj_file->shared_from_this());
    }
    return symbol_vendor;
}

//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
ConstString
SymbolVendorMacOSX::GetPluginName()
{
    return GetPluginNameStatic();
}

uint32_t
SymbolVendorMacOSX::GetPluginVersion()
{
    return 1;
}

<commit_msg>Fix some logic where we used to have char arrays, but we now use std::string. Use the correctly API to detect if they are not empty.<commit_after>//===-- SymbolVendorMacOSX.cpp ----------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "SymbolVendorMacOSX.h"

#include <string.h>

#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Host/XML.h"
#include "lldb/Symbol/ObjectFile.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// SymbolVendorMacOSX constructor
//----------------------------------------------------------------------
SymbolVendorMacOSX::SymbolVendorMacOSX(const lldb::ModuleSP &module_sp) :
    SymbolVendor (module_sp)
{
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
SymbolVendorMacOSX::~SymbolVendorMacOSX()
{
}

static bool
UUIDsMatch(Module *module, ObjectFile *ofile, lldb_private::Stream *feedback_strm)
{
    if (module && ofile)
    {
        // Make sure the UUIDs match
        lldb_private::UUID dsym_uuid;

        if (!ofile->GetUUID(&dsym_uuid))
        {
            if (feedback_strm)
            {
                feedback_strm->PutCString("warning: failed to get the uuid for object file: '");
                ofile->GetFileSpec().Dump(feedback_strm);
                feedback_strm->PutCString("\n");
            }
            return false;
        }

        if (dsym_uuid == module->GetUUID())
            return true;

        // Emit some warning messages since the UUIDs do not match!
        if (feedback_strm)
        {
            feedback_strm->PutCString("warning: UUID mismatch detected between modules:\n    ");
            module->GetUUID().Dump(feedback_strm);
            feedback_strm->PutChar(' ');
            module->GetFileSpec().Dump(feedback_strm);
            feedback_strm->PutCString("\n    ");
            dsym_uuid.Dump(feedback_strm);
            feedback_strm->PutChar(' ');
            ofile->GetFileSpec().Dump(feedback_strm);
            feedback_strm->EOL();
        }
    }
    return false;
}

void
SymbolVendorMacOSX::Initialize()
{
    PluginManager::RegisterPlugin (GetPluginNameStatic(),
                                   GetPluginDescriptionStatic(),
                                   CreateInstance);
}

void
SymbolVendorMacOSX::Terminate()
{
    PluginManager::UnregisterPlugin (CreateInstance);
}

lldb_private::ConstString
SymbolVendorMacOSX::GetPluginNameStatic()
{
    static ConstString g_name("macosx");
    return g_name;
}

const char *
SymbolVendorMacOSX::GetPluginDescriptionStatic()
{
    return "Symbol vendor for MacOSX that looks for dSYM files that match executables.";
}

//----------------------------------------------------------------------
// CreateInstance
//
// Platforms can register a callback to use when creating symbol
// vendors to allow for complex debug information file setups, and to
// also allow for finding separate debug information files.
//----------------------------------------------------------------------
SymbolVendor*
SymbolVendorMacOSX::CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm)
{
    if (!module_sp)
        return NULL;

    ObjectFile * obj_file = module_sp->GetObjectFile();
    if (!obj_file)
        return NULL;

    static ConstString obj_file_macho("mach-o");
    ConstString obj_name = obj_file->GetPluginName();
    if (obj_name != obj_file_macho)
        return NULL;

    Timer scoped_timer (__PRETTY_FUNCTION__,
                        "SymbolVendorMacOSX::CreateInstance (module = %s)",
                        module_sp->GetFileSpec().GetPath().c_str());
    SymbolVendorMacOSX* symbol_vendor = new SymbolVendorMacOSX(module_sp);
    if (symbol_vendor)
    {
        char path[PATH_MAX];
        path[0] = '\0';

        // Try and locate the dSYM file on Mac OS X
        Timer scoped_timer2 ("SymbolVendorMacOSX::CreateInstance () locate dSYM",
                             "SymbolVendorMacOSX::CreateInstance (module = %s) locate dSYM",
                             module_sp->GetFileSpec().GetPath().c_str());

        // First check to see if the module has a symbol file in mind already.
        // If it does, then we MUST use that.
        FileSpec dsym_fspec (module_sp->GetSymbolFileFileSpec());

        ObjectFileSP dsym_objfile_sp;
        if (!dsym_fspec)
        {
            // No symbol file was specified in the module, lets try and find
            // one ourselves.
            FileSpec file_spec = obj_file->GetFileSpec();
            if (!file_spec)
                file_spec = module_sp->GetFileSpec();

            ModuleSpec module_spec(file_spec, module_sp->GetArchitecture());
            module_spec.GetUUID() = module_sp->GetUUID();
            dsym_fspec = Symbols::LocateExecutableSymbolFile (module_spec);
            if (module_spec.GetSourceMappingList().GetSize())
                module_sp->GetSourceMappingList().Append (module_spec.GetSourceMappingList (), true);
        }

        if (dsym_fspec)
        {
            DataBufferSP dsym_file_data_sp;
            lldb::offset_t dsym_file_data_offset = 0;
            dsym_objfile_sp = ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(), dsym_file_data_sp, dsym_file_data_offset);
            if (UUIDsMatch(module_sp.get(), dsym_objfile_sp.get(), feedback_strm))
            {
                // We need a XML parser if we hope to parse a plist...
                if (XMLDocument::XMLEnabled())
                {
                    char dsym_path[PATH_MAX];
                    if (module_sp->GetSourceMappingList().IsEmpty() && dsym_fspec.GetPath(dsym_path, sizeof(dsym_path)))
                    {
                        lldb_private::UUID dsym_uuid;
                        if (dsym_objfile_sp->GetUUID(&dsym_uuid))
                        {
                            std::string uuid_str = dsym_uuid.GetAsString ();
                            if (!uuid_str.empty())
                            {
                                char *resources = strstr (dsym_path, "/Contents/Resources/");
                                if (resources)
                                {
                                    char dsym_uuid_plist_path[PATH_MAX];
                                    resources[strlen("/Contents/Resources/")] = '\0';
                                    snprintf(dsym_uuid_plist_path, sizeof(dsym_uuid_plist_path), "%s%s.plist", dsym_path, uuid_str.c_str());
                                    FileSpec dsym_uuid_plist_spec(dsym_uuid_plist_path, false);
                                    if (dsym_uuid_plist_spec.Exists())
                                    {
                                        ApplePropertyList plist(dsym_uuid_plist_path);
                                        if (plist)
                                        {
                                            std::string DBGBuildSourcePath;
                                            std::string DBGSourcePath;

                                            plist.GetValueAsString("DBGBuildSourcePath", DBGBuildSourcePath);
                                            plist.GetValueAsString("DBGSourcePath", DBGSourcePath);
                                            if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty())
                                            {
                                                module_sp->GetSourceMappingList().Append (ConstString(DBGBuildSourcePath), ConstString(DBGSourcePath), true);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
                return symbol_vendor;
            }
        }

        // Just create our symbol vendor using the current objfile as this is either
        // an executable with no dSYM (that we could locate), an executable with
        // a dSYM that has a UUID that doesn't match.
        symbol_vendor->AddSymbolFileRepresentation(obj_file->shared_from_this());
    }
    return symbol_vendor;
}

//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
ConstString
SymbolVendorMacOSX::GetPluginName()
{
    return GetPluginNameStatic();
}

uint32_t
SymbolVendorMacOSX::GetPluginVersion()
{
    return 1;
}

<|endoftext|>


<commit_before>#ifndef MJOLNIR_CORE_OBSERVER_CONTAINER_HPP
#define MJOLNIR_CORE_OBSERVER_CONTAINER_HPP
#include <mjolnir/util/io.hpp>
#include <mjolnir/util/progress_bar.hpp>
#include <mjolnir/core/ObserverBase.hpp>
#include <vector>

// This class manages several different XXXObservers to output
// positions, energies, topologies, and others.
//
// Also, this class outputs progress bar into stdout if the flag is on.

namespace mjolnir
{

template<typename traitsT>
class ObserverContainer
{
  public:
    using observer_base_type = ObserverBase<traitsT>;
    using observer_base_ptr  = std::unique_ptr<observer_base_type>;
    using real_type          = typename observer_base_type::real_type;
    using coordinate_type    = typename observer_base_type::coordinate_type;
    using system_type        = typename observer_base_type::system_type;
    using forcefield_type    = typename observer_base_type::forcefield_type;
    using progress_bar_type  = progress_bar</*width of bar = */50>;

  public:

    explicit ObserverContainer(bool output_progress = false)
        : output_progress_(output_progress && io::detail::isatty(std::cerr))
    {}
    ~ObserverContainer() = default;

    ObserverContainer(const ObserverContainer&) = default;
    ObserverContainer(ObserverContainer&&)      = default;
    ObserverContainer& operator=(const ObserverContainer&) = default;
    ObserverContainer& operator=(ObserverContainer&&)      = default;

    // open files, write header and so on.
    void initialize(const std::size_t total_step, const real_type dt,
                    const system_type& sys, const forcefield_type& ff)
    {
        for(const auto& obs : observers_)
        {
            obs->initialize(total_step, dt, sys, ff);
        }

        this->progress_bar_.reset(total_step); // set total_step as 100%.
    }
    // call if system or forcefield is changed.
    void update(const std::size_t step, const real_type dt,
                const system_type& sys, const forcefield_type& ff)
    {
        for(const auto& obs : this->observers_)
        {
            obs->update(step, dt, sys, ff);
        }
    }
    // output the current state.
    void output(const std::size_t step, const real_type dt,
                const system_type& sys, const forcefield_type& ff)
    {
        for(const auto& obs : this->observers_)
        {
            obs->output(step, dt, sys, ff);
        }

        // this branching might be wiped out by introducing another parameter
        // to SimulatorTraits, but I don't think the cost of the implementation
        // is larger than the benefit on the runtime efficiency.
        if(this->output_progress_)
        {
            this->progress_bar_.format(step, std::cerr);
        }
    }
    // update header, or something that required to be finalized
    void finalize(const std::size_t total_step, const real_type dt,
                  const system_type& sys, const forcefield_type& ff)
    {
        for(const auto& obs : this->observers_)
        {
            obs->finalize(total_step, dt, sys, ff);
        }

        if(this->output_progress_)
        {
            // In order to re-write progress bar in each step, it does not print
            // end-line after the progress bar. But if finalize is called, we
            // can `finalize` the progress bar.
            std::cerr << std::endl;
        }
    }

    // assign one another XXXObserver
    void push_back(observer_base_ptr&& obs)
    {
        this->observers_.push_back(std::move(obs));
    }

    // mainly for testing purpose.
    std::vector<observer_base_ptr> const& observers() const noexcept
    {
        return this->observers_;
    }

  private:
    std::vector<observer_base_ptr> observers_;
    progress_bar_type              progress_bar_;
    bool                           output_progress_;
};

#ifdef MJOLNIR_SEPARATE_BUILD
extern template class ObserverContainer<SimulatorTraits<double, UnlimitedBoundary>       >;
extern template class ObserverContainer<SimulatorTraits<float,  UnlimitedBoundary>       >;
extern template class ObserverContainer<SimulatorTraits<double, CuboidalPeriodicBoundary>>;
extern template class ObserverContainer<SimulatorTraits<float,  CuboidalPeriodicBoundary>>;
#endif

} // mjolnir
#endif// MJOLNIR_CORE_OBSERVER_HPP
<commit_msg>feat: add prefix() to ObserverContainer<commit_after>#ifndef MJOLNIR_CORE_OBSERVER_CONTAINER_HPP
#define MJOLNIR_CORE_OBSERVER_CONTAINER_HPP
#include <mjolnir/util/io.hpp>
#include <mjolnir/util/progress_bar.hpp>
#include <mjolnir/core/ObserverBase.hpp>
#include <vector>

// This class manages several different XXXObservers to output
// positions, energies, topologies, and others.
//
// Also, this class outputs progress bar into stdout if the flag is on.

namespace mjolnir
{

template<typename traitsT>
class ObserverContainer
{
  public:
    using observer_base_type = ObserverBase<traitsT>;
    using observer_base_ptr  = std::unique_ptr<observer_base_type>;
    using real_type          = typename observer_base_type::real_type;
    using coordinate_type    = typename observer_base_type::coordinate_type;
    using system_type        = typename observer_base_type::system_type;
    using forcefield_type    = typename observer_base_type::forcefield_type;
    using progress_bar_type  = progress_bar</*width of bar = */50>;

  public:

    explicit ObserverContainer(bool output_progress = false)
        : output_progress_(output_progress && io::detail::isatty(std::cerr))
    {}
    ~ObserverContainer() = default;

    ObserverContainer(const ObserverContainer&) = default;
    ObserverContainer(ObserverContainer&&)      = default;
    ObserverContainer& operator=(const ObserverContainer&) = default;
    ObserverContainer& operator=(ObserverContainer&&)      = default;

    // open files, write header and so on.
    void initialize(const std::size_t total_step, const real_type dt,
                    const system_type& sys, const forcefield_type& ff)
    {
        for(const auto& obs : observers_)
        {
            obs->initialize(total_step, dt, sys, ff);
        }

        this->progress_bar_.reset(total_step); // set total_step as 100%.
    }
    // call if system or forcefield is changed.
    void update(const std::size_t step, const real_type dt,
                const system_type& sys, const forcefield_type& ff)
    {
        for(const auto& obs : this->observers_)
        {
            obs->update(step, dt, sys, ff);
        }
    }
    // output the current state.
    void output(const std::size_t step, const real_type dt,
                const system_type& sys, const forcefield_type& ff)
    {
        for(const auto& obs : this->observers_)
        {
            obs->output(step, dt, sys, ff);
        }

        // this branching might be wiped out by introducing another parameter
        // to SimulatorTraits, but I don't think the cost of the implementation
        // is larger than the benefit on the runtime efficiency.
        if(this->output_progress_)
        {
            this->progress_bar_.format(step, std::cerr);
        }
    }
    // update header, or something that required to be finalized
    void finalize(const std::size_t total_step, const real_type dt,
                  const system_type& sys, const forcefield_type& ff)
    {
        for(const auto& obs : this->observers_)
        {
            obs->finalize(total_step, dt, sys, ff);
        }

        if(this->output_progress_)
        {
            // In order to re-write progress bar in each step, it does not print
            // end-line after the progress bar. But if finalize is called, we
            // can `finalize` the progress bar.
            std::cerr << std::endl;
        }
    }

    std::string prefix() const
    {
        return observers_.front()->prefix();
    }

    // assign one another XXXObserver
    void push_back(observer_base_ptr&& obs)
    {
        this->observers_.push_back(std::move(obs));
    }

    // mainly for testing purpose.
    std::vector<observer_base_ptr> const& observers() const noexcept
    {
        return this->observers_;
    }

  private:
    std::vector<observer_base_ptr> observers_;
    progress_bar_type              progress_bar_;
    bool                           output_progress_;
};

#ifdef MJOLNIR_SEPARATE_BUILD
extern template class ObserverContainer<SimulatorTraits<double, UnlimitedBoundary>       >;
extern template class ObserverContainer<SimulatorTraits<float,  UnlimitedBoundary>       >;
extern template class ObserverContainer<SimulatorTraits<double, CuboidalPeriodicBoundary>>;
extern template class ObserverContainer<SimulatorTraits<float,  CuboidalPeriodicBoundary>>;
#endif

} // mjolnir
#endif// MJOLNIR_CORE_OBSERVER_HPP
<|endoftext|>


<commit_before>#ifndef MJOLNIR_READ_INTERACTION
#define MJOLNIR_READ_INTERACTION
#include <extlib/toml/toml.hpp>
#include <mjolnir/core/LocalInteractionBase.hpp>
#include <mjolnir/core/BondLengthInteraction.hpp>
#include <mjolnir/core/BondAngleInteraction.hpp>
#include <mjolnir/core/DihedralAngleInteraction.hpp>
#include <mjolnir/core/GlobalInteractionBase.hpp>
#include <mjolnir/core/GlobalDistanceInteraction.hpp>
#include <mjolnir/core/ZaxisExternalForceInteraction.hpp>
#include <mjolnir/util/make_unique.hpp>
#include <mjolnir/util/throw_exception.hpp>
#include <mjolnir/input/get_toml_value.hpp>
#include <mjolnir/input/read_potential.hpp>
#include <mjolnir/input/read_spatial_partition.hpp>
#include <memory>

namespace mjolnir
{

// ----------------------------------------------------------------------------
// local interaction
// ----------------------------------------------------------------------------

template<typename traitsT>
std::unique_ptr<LocalInteractionBase<traitsT>>
read_bond_length_interaction(
    const typename LocalInteractionBase<traitsT>::connection_kind_type kind,
    const toml::Table& local)
{
    const auto potential = toml::get<std::string>(
            toml_value_at(local, "potential", "[forcefield.local]"));

    if(potential == "Harmonic")
    {
        using potential_t = HarmonicPotential<traitsT>;

        return make_unique<BondLengthInteraction<traitsT, potential_t>>(
            kind, read_harmonic_potential<traitsT, 2>(local));
    }
    else if(potential == "Go1012Contact")
    {
        using potential_t = Go1012ContactPotential<traitsT>;

        return make_unique<BondLengthInteraction<traitsT, potential_t>>(
            kind, read_go1012_contact_potential<traitsT, 2>(local));
    }
    else if(potential == "AICG2PlusAngle")
    {
        using potential_t = GaussianPotential<traitsT>;

        return make_unique<BondLengthInteraction<traitsT, potential_t>>(
            kind, read_gaussian_potential<traitsT, 2>(local));
    }
    else
    {
        throw_exception<std::runtime_error>(
                "invalid potential as BondLengthInteraction: ", potential);
    }
}

template<typename traitsT>
std::unique_ptr<LocalInteractionBase<traitsT>>
read_bond_angle_interaction(
    const typename LocalInteractionBase<traitsT>::connection_kind_type kind,
    const toml::Table& local)
{
    const auto potential = toml::get<std::string>(
            toml_value_at(local, "potential", "[[forcefield.local]]"));
    if(potential == "Harmonic")
    {
        using potential_t = HarmonicPotential<traitsT>;

        return make_unique<BondAngleInteraction<traitsT, potential_t>>(
            kind, read_harmonic_potential<traitsT, 3>(local));
    }
    else if(potential == "FlexibleLocalAngle")
    {
        using potential_t = FlexibleLocalAnglePotential<traitsT>;

        return make_unique<BondAngleInteraction<traitsT, potential_t>>(
            kind, read_flexible_local_angle_potential<traitsT, 3>(local));
    }
    else
    {
        throw_exception<std::runtime_error>(
                "invalid potential as BondAngleInteraction: " + potential);
    }
}

template<typename traitsT>
std::unique_ptr<LocalInteractionBase<traitsT>>
read_dihedral_angle_interaction(
    const typename LocalInteractionBase<traitsT>::connection_kind_type kind,
    const toml::Table& local)
{
    const auto potential = toml::get<std::string>(
            toml_value_at(local, "potential", "[forcefield.local]"));
    if(potential == "Harmonic")
    {
        using potential_t = HarmonicPotential<traitsT>;

        return make_unique<DihedralAngleInteraction<traitsT, potential_t>>(
            kind, read_harmonic_potential<traitsT, 4>(local));
    }
    else if(potential == "ClementiDihedral")
    {
        using potential_t = ClementiDihedralPotential<traitsT>;

        return make_unique<DihedralAngleInteraction<traitsT, potential_t>>(
            kind, read_clementi_dihedral_potential<traitsT, 4>(local));
    }
    else if(potential == "AICG2PlusDihedral")
    {
        using potential_t = GaussianPotential<traitsT>;

        return make_unique<DihedralAngleInteraction<traitsT, potential_t>>(
            kind, read_gaussian_potential<traitsT, 4>(local));
    }
    else if(potential == "FlexibleLocalDihedral")
    {
        using potential_t = FlexibleLocalDihedralPotential<traitsT>;

        return make_unique<DihedralAngleInteraction<traitsT, potential_t>>(
            kind, read_flexible_local_dihedral_potential<traitsT, 4>(local));
    }
    else
    {
        throw_exception<std::runtime_error>(
                "invalid potential as DihedralAngleInteraction: " + potential);
    }
}

// ----------------------------------------------------------------------------
// global interaction
// ----------------------------------------------------------------------------

template<typename traitsT, typename ignoreT>
std::unique_ptr<GlobalInteractionBase<traitsT>>
read_global_distance_interaction(const toml::Table& global)
{
    const auto potential = toml::get<std::string>(
            toml_value_at(global, "potential", "[forcefield.local]"));
    if(potential == "ExcludedVolume")
    {
        using potential_t = ExcludedVolumePotential<traitsT, ignoreT>;

        return read_spatial_partition_for_distance<traitsT, potential_t>(
            global, read_excluded_volume_potential<traitsT, ignoreT>(global));
    }
    else if(potential == "DebyeHuckel")
    {
        using potential_t = DebyeHuckelPotential<traitsT, ignoreT>;

        return read_spatial_partition_for_distance<traitsT, potential_t>(
            global, read_debye_huckel_potential<traitsT, ignoreT>(global));
    }
    else if(potential == "LennardJones")
    {
        using potential_t = LennardJonesPotential<traitsT, ignoreT>;

        return read_spatial_partition_for_distance<traitsT, potential_t>(
            global, read_lennard_jones_potential<traitsT, ignoreT>(global));
    }
    else
    {
        throw_exception<std::runtime_error>(
                "invalid potential as GlobalDistanceInteraction: " + potential);
    }
}

template<typename traitsT>
std::unique_ptr<GlobalInteractionBase<traitsT>>
read_zaxis_external_force_interaction(const toml::Table& global)
{
    const auto potential = toml::get<std::string>(
            toml_value_at(global, "potential", "[forcefield.local]"));
    if(potential == "ImplicitMembrane")
    {
        return read_spatial_partition_for_implicit_membrane<
            traitsT, ImplicitMembranePotential<traitsT>>(
                global, read_implicit_membrane_potential<traitsT>(global));
    }
    else
    {
        throw std::runtime_error("invalid distance potential: " + potential);
    }
}

// ----------------------------------------------------------------------------
// general read_(local|global)_interaction function
// ----------------------------------------------------------------------------

template<typename traitsT>
std::unique_ptr<LocalInteractionBase<traitsT>>
read_local_interaction(const toml::Table& local)
{
    const auto interaction = toml::get<std::string>(
            toml_value_at(local, "interaction", "[forcefields.local]"));

    // topology stuff
    using connection_kind_type =
        typename LocalInteractionBase<traitsT>::connection_kind_type;
    const auto connection = toml::get<std::string>(
            toml_value_at(local, "topology", "[forcefield.local]"));

    connection_kind_type kind;
    if     (connection == "bond")    {kind = connection_kind_type::bond;}
    else if(connection == "contact") {kind = connection_kind_type::contact;}
    else if(connection == "none")    {kind = connection_kind_type::none;}
    else {throw std::runtime_error("invalid connection type: " + connection);}

    if(interaction == "BondLength")
    {
        return read_bond_length_interaction<traitsT>(kind, local);
    }
    else if(interaction == "BondAngle")
    {
        return read_bond_angle_interaction<traitsT>(kind, local);
    }
    else if(interaction == "DihedralAngle")
    {
        return read_dihedral_angle_interaction<traitsT>(kind, local);
    }
    else
    {
        throw std::runtime_error(
                "invalid local interaction type: " + interaction);
    }
}

template<typename traitsT>
std::unique_ptr<GlobalInteractionBase<traitsT>>
read_global_interaction(const toml::Table& global)
{
    const auto interaction = toml::get<std::string>(
            toml_value_at(global, "interaction", "[forcefields.global]"));
    const auto ignored_chain = toml::get<std::string>(
            toml_value_at(global, "ignored_chain", "[forcefields.global]"));

    if(interaction == "Distance")
    {
        if(ignored_chain == "Nothing")
        {
            return read_global_distance_interaction<traitsT, IgnoreNothing>(global);
        }
        else if(ignored_chain == "Self")
        {
            return read_global_distance_interaction<traitsT, IgnoreSelf>(global);
        }
        else if(ignored_chain == "Others")
        {
            return read_global_distance_interaction<traitsT, IgnoreOthers>(global);
        }
        else
        {
            throw std::runtime_error("invalid `ignored_chain`: " + ignored_chain);
        }
    }
    else if(interaction == "External")
    {
        return read_zaxis_external_force_interaction<traitsT>(global);
    }
    else
    {
        throw std::runtime_error(
                "invalid global interaction type: " + interaction);
    }
}

} // mjolnir
#endif// MJOLNIR_READ_INTERACTION
<commit_msg>add read_external interaction and shape<commit_after>#ifndef MJOLNIR_READ_INTERACTION
#define MJOLNIR_READ_INTERACTION
#include <extlib/toml/toml.hpp>
#include <mjolnir/core/BondLengthInteraction.hpp>
#include <mjolnir/core/BondAngleInteraction.hpp>
#include <mjolnir/core/DihedralAngleInteraction.hpp>
#include <mjolnir/core/GlobalDistanceInteraction.hpp>
#include <mjolnir/core/AxisAlignedPlane.hpp>
#include <mjolnir/core/ExternalDistanceInteraction.hpp>
#include <mjolnir/util/make_unique.hpp>
#include <mjolnir/util/throw_exception.hpp>
#include <mjolnir/input/get_toml_value.hpp>
#include <mjolnir/input/read_potential.hpp>
#include <mjolnir/input/read_spatial_partition.hpp>
#include <memory>

namespace mjolnir
{

// ----------------------------------------------------------------------------
// local interaction
// ----------------------------------------------------------------------------

template<typename traitsT>
std::unique_ptr<LocalInteractionBase<traitsT>>
read_bond_length_interaction(
    const typename LocalInteractionBase<traitsT>::connection_kind_type kind,
    const toml::Table& local)
{
    const auto potential = toml::get<std::string>(
            toml_value_at(local, "potential", "[forcefield.local]"));

    if(potential == "Harmonic")
    {
        using potential_t = HarmonicPotential<traitsT>;

        return make_unique<BondLengthInteraction<traitsT, potential_t>>(
            kind, read_harmonic_potential<traitsT, 2>(local));
    }
    else if(potential == "Go1012Contact")
    {
        using potential_t = Go1012ContactPotential<traitsT>;

        return make_unique<BondLengthInteraction<traitsT, potential_t>>(
            kind, read_go1012_contact_potential<traitsT, 2>(local));
    }
    else if(potential == "AICG2PlusAngle")
    {
        using potential_t = GaussianPotential<traitsT>;

        return make_unique<BondLengthInteraction<traitsT, potential_t>>(
            kind, read_gaussian_potential<traitsT, 2>(local));
    }
    else
    {
        throw_exception<std::runtime_error>(
                "invalid potential as BondLengthInteraction: ", potential);
    }
}

template<typename traitsT>
std::unique_ptr<LocalInteractionBase<traitsT>>
read_bond_angle_interaction(
    const typename LocalInteractionBase<traitsT>::connection_kind_type kind,
    const toml::Table& local)
{
    const auto potential = toml::get<std::string>(
            toml_value_at(local, "potential", "[[forcefield.local]]"));
    if(potential == "Harmonic")
    {
        using potential_t = HarmonicPotential<traitsT>;

        return make_unique<BondAngleInteraction<traitsT, potential_t>>(
            kind, read_harmonic_potential<traitsT, 3>(local));
    }
    else if(potential == "FlexibleLocalAngle")
    {
        using potential_t = FlexibleLocalAnglePotential<traitsT>;

        return make_unique<BondAngleInteraction<traitsT, potential_t>>(
            kind, read_flexible_local_angle_potential<traitsT, 3>(local));
    }
    else
    {
        throw_exception<std::runtime_error>(
                "invalid potential as BondAngleInteraction: " + potential);
    }
}

template<typename traitsT>
std::unique_ptr<LocalInteractionBase<traitsT>>
read_dihedral_angle_interaction(
    const typename LocalInteractionBase<traitsT>::connection_kind_type kind,
    const toml::Table& local)
{
    const auto potential = toml::get<std::string>(
            toml_value_at(local, "potential", "[forcefield.local]"));
    if(potential == "Harmonic")
    {
        using potential_t = HarmonicPotential<traitsT>;

        return make_unique<DihedralAngleInteraction<traitsT, potential_t>>(
            kind, read_harmonic_potential<traitsT, 4>(local));
    }
    else if(potential == "ClementiDihedral")
    {
        using potential_t = ClementiDihedralPotential<traitsT>;

        return make_unique<DihedralAngleInteraction<traitsT, potential_t>>(
            kind, read_clementi_dihedral_potential<traitsT, 4>(local));
    }
    else if(potential == "AICG2PlusDihedral")
    {
        using potential_t = GaussianPotential<traitsT>;

        return make_unique<DihedralAngleInteraction<traitsT, potential_t>>(
            kind, read_gaussian_potential<traitsT, 4>(local));
    }
    else if(potential == "FlexibleLocalDihedral")
    {
        using potential_t = FlexibleLocalDihedralPotential<traitsT>;

        return make_unique<DihedralAngleInteraction<traitsT, potential_t>>(
            kind, read_flexible_local_dihedral_potential<traitsT, 4>(local));
    }
    else
    {
        throw_exception<std::runtime_error>(
                "invalid potential as DihedralAngleInteraction: " + potential);
    }
}

// ----------------------------------------------------------------------------
// global interaction
// ----------------------------------------------------------------------------

template<typename traitsT, typename ignoreT>
std::unique_ptr<GlobalInteractionBase<traitsT>>
read_global_distance_interaction(const toml::Table& global)
{
    const auto potential = toml::get<std::string>(
            toml_value_at(global, "potential", "[forcefield.global]"));
    if(potential == "ExcludedVolume")
    {
        using potential_t = ExcludedVolumePotential<traitsT, ignoreT>;

        return read_spatial_partition_for_distance<traitsT, potential_t>(
            global, read_excluded_volume_potential<traitsT, ignoreT>(global));
    }
    else if(potential == "DebyeHuckel")
    {
        using potential_t = DebyeHuckelPotential<traitsT, ignoreT>;

        return read_spatial_partition_for_distance<traitsT, potential_t>(
            global, read_debye_huckel_potential<traitsT, ignoreT>(global));
    }
    else if(potential == "LennardJones")
    {
        using potential_t = LennardJonesPotential<traitsT, ignoreT>;

        return read_spatial_partition_for_distance<traitsT, potential_t>(
            global, read_lennard_jones_potential<traitsT, ignoreT>(global));
    }
    else
    {
        throw_exception<std::runtime_error>(
                "invalid potential as GlobalDistanceInteraction: ", potential);
    }
}

// ----------------------------------------------------------------------------
// external interaction
// ----------------------------------------------------------------------------

template<typename traitsT, typename shapeT>
std::unique_ptr<ExternalForceInteractionBase<traitsT>>
read_external_distance_interaction(const toml::Table& external, shapeT&& shape)
{
    using real_type = typename traitsT::real_type;
    const auto potential = toml::get<std::string>(toml_value_at(external,
                "potential", "[forcefield.external]"));

    if(potential == "ImplicitMembrane")
    {
        using potential_t   = ImplicitMembranePotential<traitsT>;
        using interaction_t = ExternalDistanceInteraction<
                                    traitsT, potential_t, shapeT>;

        return make_unique<interaction_t>(std::move(shape),
             read_implicit_membrane_potential<traitsT>(external));
    }
    else
    {
        throw_exception<std::runtime_error>(
            "invalid potential as ExternalDistanceInteraction: ", potential);
    }
}

template<typename traitsT>
std::unique_ptr<ExternalForceInteractionBase<traitsT>>
read_external_distance_interaction_shape(const toml::Table& external)
{
    using real_type = typename traitsT::real_type;

    const auto shape = toml::get<toml::Table>(toml_value_at(external, "shape",
            "[forcefield.external] for ExternalDistance"));
    const auto name  = toml::get<std::string>(toml_value_at(shape, "name",
            "[forcefield.external.shape] for ExternalDistance"));

    if(name == "AxisAlignedPlane")
    {
        const auto pos = toml::get<real_type>(toml_value_at(shape, "position",
            "[forcefield.external.shape] for ExternalDistance"));
        const auto mergin = toml::get<real_type>(toml_value_at(shape, "mergin",
            "[forcefield.external.shape] for ExternalDistance"));

        const auto axis = toml::get<std::string>(toml_value_at(shape, "axis",
            "[forcefield.external.shape] for ExternalDistance"));
        if(axis == "X")
        {
            using shape_t = AxisAlignedPlane<traitsT, 0>;
            return read_external_distance_interaction<traitsT, shape_t>(
                    external, shape_t(pos, mergin));
        }
        else if(axis == "Y")
        {
            using shape_t = AxisAlignedPlane<traitsT, 1>;
            return read_external_distance_interaction<traitsT, shape_t>(
                    external, shape_t(pos, mergin));
        }
        else if(axis == "Z")
        {
            using shape_t = AxisAlignedPlane<traitsT, 2>;
            return read_external_distance_interaction<traitsT, shape_t>(
                    external, shape_t(pos, mergin));
        }
        else
        {
            throw std::runtime_error("invalid axis name: " + axis);
        }
    }
    else
    {
        throw std::runtime_error("invalid external forcefield shape: " + name);
    }
}

// ----------------------------------------------------------------------------
// general read_(local|global|external)_interaction function
// ----------------------------------------------------------------------------

template<typename traitsT>
std::unique_ptr<LocalInteractionBase<traitsT>>
read_local_interaction(const toml::Table& local)
{
    const auto interaction = toml::get<std::string>(
            toml_value_at(local, "interaction", "[forcefields.local]"));

    // topology stuff
    using connection_kind_type =
        typename LocalInteractionBase<traitsT>::connection_kind_type;
    const auto connection = toml::get<std::string>(
            toml_value_at(local, "topology", "[forcefield.local]"));

    connection_kind_type kind;
    if     (connection == "bond")    {kind = connection_kind_type::bond;}
    else if(connection == "contact") {kind = connection_kind_type::contact;}
    else if(connection == "none")    {kind = connection_kind_type::none;}
    else {throw std::runtime_error("invalid connection type: " + connection);}

    if(interaction == "BondLength")
    {
        return read_bond_length_interaction<traitsT>(kind, local);
    }
    else if(interaction == "BondAngle")
    {
        return read_bond_angle_interaction<traitsT>(kind, local);
    }
    else if(interaction == "DihedralAngle")
    {
        return read_dihedral_angle_interaction<traitsT>(kind, local);
    }
    else
    {
        throw std::runtime_error(
                "invalid local interaction type: " + interaction);
    }
}

template<typename traitsT>
std::unique_ptr<GlobalInteractionBase<traitsT>>
read_global_interaction(const toml::Table& global)
{
    const auto interaction = toml::get<std::string>(
            toml_value_at(global, "interaction", "[forcefields.global]"));
    const auto ignored_chain = toml::get<std::string>(
            toml_value_at(global, "ignored_chain", "[forcefields.global]"));

    if(interaction == "Distance")
    {
        if(ignored_chain == "Nothing")
        {
            return read_global_distance_interaction<traitsT, IgnoreNothing>(global);
        }
        else if(ignored_chain == "Self")
        {
            return read_global_distance_interaction<traitsT, IgnoreSelf>(global);
        }
        else if(ignored_chain == "Others")
        {
            return read_global_distance_interaction<traitsT, IgnoreOthers>(global);
        }
        else
        {
            throw std::runtime_error("invalid `ignored_chain`: " + ignored_chain);
        }
    }
    else
    {
        throw std::runtime_error(
                "invalid global interaction type: " + interaction);
    }
}

template<typename traitsT>
std::unique_ptr<ExternalForceInteractionBase<traitsT>>
read_external_interaction(const toml::Table& external)
{
    const auto interaction = toml::get<std::string>(
            toml_value_at(external, "interaction", "[forcefields.external]"));

    if(interaction == "Distance")
    {
        return read_external_distance_interaction_shape<traitsT>(external);
    }
    else
    {
        throw std::runtime_error(
                "invalid global interaction type: " + interaction);
    }
}

} // mjolnir
#endif// MJOLNIR_READ_INTERACTION
<|endoftext|>