Exemple #1
0
int
seafile_log_init (const char *_logfile, const char *ccnet_debug_level_str,
                  const char *seafile_debug_level_str)
{
    g_log_set_handler (NULL, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL
                       | G_LOG_FLAG_RECURSION, seafile_log, NULL);
    g_log_set_handler ("Ccnet", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL
                       | G_LOG_FLAG_RECURSION, ccnet_log, NULL);

    /* record all log message */
    ccnet_log_level = get_debug_level(ccnet_debug_level_str, G_LOG_LEVEL_INFO);
    seafile_log_level = get_debug_level(seafile_debug_level_str, G_LOG_LEVEL_DEBUG);

    if (strcmp(_logfile, "-") == 0) {
        logfp = stdout;
        logfile = g_strdup (_logfile);
    }
    else {
        logfile = ccnet_expand_path(_logfile);
        if ((logfp = g_fopen (logfile, "a+")) == NULL) {
            seaf_message ("Failed to open file %s\n", logfile);
            return -1;
        }
    }

    return 0;
}
Exemple #2
0
double PropsSI(const std::string &Output, const std::string &Name1, double Prop1, const std::string &Name2, double Prop2, const std::string &Ref)
{
	std::string backend, fluid;
	#if !defined(PROPSSI_NO_ERROR_CATCH)
    // In this function the error catching happens;
    try{
	#else
	std::cout << "macro is on; error checking disabled in PropsSI" << std::endl;
	#endif
        // BEGIN OF TRY
		// Here is the real code that is inside the try block
		extract_backend(Ref, backend, fluid);
		double val = _PropsSI(Output, Name1, Prop1, Name2, Prop2, backend, fluid, std::vector<double>());
		if (get_debug_level() > 1){ std::cout << format("_PropsSI will return %g",val) << std::endl; }
        return val;
        // END OF TRY
	#if !defined(PROPSSI_NO_ERROR_CATCH)
    }
    catch(const std::exception& e){
		set_error_string(e.what() + format(" : PropsSI(\"%s\",\"%s\",%0.10g,\"%s\",%0.10g,\"%s\")",Output.c_str(),Name1.c_str(), Prop1, Name2.c_str(), Prop2, Ref.c_str())); 
		#if defined (PROPSSI_ERROR_STDOUT)
		std::cout << e.what() << std::endl; 
		#endif
		if (get_debug_level() > 1){std::cout << e.what() << std::endl;}
		return _HUGE; 
	}
    catch(...){
		return _HUGE; 
	}
	#endif
}
/**
@param fractions The vector of fractions of the components converted to the correct input
*/
void IncompressibleBackend::set_fractions(const std::vector<long double> &fractions){
	if (get_debug_level()>=10) std::cout << format("Incompressible backend: Called set_fractions with %s ",vec_to_string(fractions).c_str()) << std::endl;
	if (fractions.size()!=1) throw ValueError(format("The incompressible backend only supports one entry in the fraction vector and not %d.",fractions.size()));
	if ( ( this->_fractions.size()!=1 ) ||
		 ( this->_fractions[0]!=fractions[0] ) ) { // Change it!
		if (get_debug_level()>=20) std::cout << format("Incompressible backend: Updating the fractions triggered a change in reference state %s -> %s",vec_to_string(this->_fractions).c_str(),vec_to_string(fractions).c_str()) << std::endl;
		this->_fractions = fractions;
		fluid->set_reference_state(fluid->getTref(), fluid->getpref(), this->_fractions[0], fluid->gethref(), fluid->getsref());
	}
}
Exemple #4
0
double _CoolProp_Fluid_Props(long iOutput, long iName1, double Prop1, long iName2, double Prop2, Fluid *pFluid, bool SinglePhase)
{
	double val = _HUGE;
	// This private method uses the indices directly for speed

	if (get_debug_level()>3){
		std::cout<<__FILE__<<" _CoolProp_Fluid_Props: "<<iOutput<<","<<iName1<<","<<Prop1<<","<<iName2<<","<<Prop2<<","<<pFluid->get_name().c_str()<<std::endl;
	}

	// Generate a State instance wrapped around the Fluid instance
	CoolPropStateClass CPS(pFluid);

	// Check if it is an output that doesn't require a state input
	// Deal with it and return

	switch (iOutput)
	{
		case iMM:
		case iPcrit:
		case iTcrit:
		case iTtriple:
		case iPtriple:
		case iRhocrit:
		case iTmin:
		case iAccentric:
		case iPHASE_LIQUID:
		case iPHASE_GAS:
		case iPHASE_SUPERCRITICAL:
		case iPHASE_TWOPHASE:
		case iGWP20:
		case iGWP100:
		case iGWP500:
		case iODP:
		case iCritSplineT:
		case iScrit:
		case iHcrit:
		case iTreduce:
		case iRhoreduce:
			return CPS.keyed_output(iOutput);
	}

	// Update the class
	CPS.update(iName1,Prop1,iName2,Prop2);
	// Get the output
	val = CPS.keyed_output(iOutput);
	
	if (get_debug_level()>5){
		std::cout<<__FILE__<<" _CoolProp_Fluid_Props return: "<<val<<std::endl;
	}
	// Return the value
	return val;
}
bool is_valid_second_derivative(const std::string & name, parameters &iOf1, parameters &iWrt1, parameters &iConstant1, parameters &iWrt2, parameters &iConstant2)
{
    if (get_debug_level() > 5){std::cout << format("is_valid_second_derivative(%s)",name.c_str());}
    
    // Suppose we start with "d(d(P)/d(Dmolar)|T)/d(Dmolar)|T"
    std::size_t i_bar = name.rfind('|');
    if (i_bar == std::string::npos){return false;}
    std::string constant2 = name.substr(i_bar+1); // "T"
    if (!is_valid_parameter(constant2, iConstant2)){return false;};
    std::string left_of_bar = name.substr(0, i_bar); // "d(d(P)/d(Dmolar)|T)/d(Dmolar)"
    
    std::size_t i_slash = left_of_bar.rfind('/');
    if (i_slash == std::string::npos){return false;}
    
    std::string left_of_slash = left_of_bar.substr(0, i_slash); // "d(d(P)/d(Dmolar)|T)"
    std::size_t iN0 = left_of_slash.find("(");
    std::size_t iN1 = left_of_slash.rfind(")");
    if (!(iN0 > 0 && iN1 > 0 && iN1 > iN0)){return false;}
    std::string num = left_of_slash.substr(iN0+1, iN1-2); // "d(P)/d(Dmolar)|T"
    if (!is_valid_first_derivative(num, iOf1, iWrt1, iConstant1)){return false;}
    
    std::string right_of_slash = left_of_bar.substr(i_slash+1); // "d(Dmolar)"
    std::size_t iD0 = right_of_slash.find("(");
    std::size_t iD1 = right_of_slash.rfind(")");
    if (!(iD0 > 0 && iD1 > 0 && iD1 > iD0)){return false;}
    std::string den = right_of_slash.substr(iD0+1, iD1-2); // "Dmolar"
    if (!is_valid_parameter(den, iWrt2)){return false;}
    
    // If we haven't quit yet, all is well
    return true;
}
bool is_valid_first_derivative(const std::string & name, parameters &iOf, parameters &iWrt, parameters &iConstant)
{
    std::size_t iN0, iN1, iD0, iD1;
    parameters Of, Wrt, Constant;
    if (get_debug_level() > 5){std::cout << format("is_valid_first_derivative(%s)",name.c_str());}
    // There should be exactly one /
    // There should be exactly one |
    
    // Suppose we start with "d(P)/d(T)|Dmolar"
    std::vector<std::string> split_at_bar = strsplit(name, '|'); // "d(P)/d(T)"  and "Dmolar"
    if (split_at_bar.size() != 2){return false;}
    
    std::vector<std::string> split_at_slash = strsplit(split_at_bar[0], '/'); // "d(P)" and "d(T)"
    if (split_at_slash.size() != 2){return false;}
    
    iN0 = split_at_slash[0].find("(");
    iN1 = split_at_slash[0].find(")", iN0);
    if (!(iN0 > 0 && iN1 > 0 && iN1 > iN0)){return false;}
    std::string num = split_at_slash[0].substr(iN0+1, iN1-2);
    
    iD0 = split_at_slash[1].find("(");
    iD1 = split_at_slash[1].find(")", iD0);
    if (!(iD0 > 0 && iD1 > 0 && iD1 > iD0)){return false;}
    std::string den = split_at_slash[1].substr(iD0+1, iD1-2);
    
    if (is_valid_parameter(num, Of) && is_valid_parameter(den, Wrt) && is_valid_parameter(split_at_bar[1], Constant)){
        iOf = Of; iWrt = Wrt; iConstant = Constant; return true;
    }
    else{
        return false;
    }
}
bool is_valid_second_derivative(const std::string &name, parameters &iOf1, parameters &iWrt1, parameters &iConstant1, parameters &iWrt2, parameters &iConstant2)
{
    if (get_debug_level() > 5){std::cout << format("is_valid_second_derivative(%s)",name.c_str());}
    
    // Suppose we start with "d(d(P)/d(Dmolar)|T)/d(Dmolar)|T"
    std::size_t i = name.rfind('|');
    if ((i == 0) || (i == std::string::npos)){return false;}
    std::string constant2 = name.substr(i+1); // "T"
    if (!is_valid_parameter(constant2, iConstant2)){return false;};
    std::string left_of_bar = name.substr(0, i); // "d(d(P)/d(Dmolar)|T)/d(Dmolar)"
    
    i = left_of_bar.rfind('/');
    if ((i == 0) || (i == std::string::npos)){return false;}
    std::string left_of_slash = left_of_bar.substr(0, i); // "d(d(P)/d(Dmolar)|T)"
    std::string right_of_slash = left_of_bar.substr(i + 1); // "d(Dmolar)"

    i = left_of_slash.find("(");
    std::size_t i1 = left_of_slash.rfind(")");
    if (!((i > 0) && (i != std::string::npos) && (i1 > (i+1)) && (i1 != std::string::npos))){return false;}
    std::string num = left_of_slash.substr(i+1, i1-i-1); // "d(P)/d(Dmolar)|T"
    if (!is_valid_first_derivative(num, iOf1, iWrt1, iConstant1)){return false;}
    
    i = right_of_slash.find("(");
    i1 = right_of_slash.rfind(")");
    if (!((i > 0) && (i != std::string::npos) && (i1 > (i+1)) && (i1 != std::string::npos))){return false;}
    std::string den = right_of_slash.substr(i+1, i1-i-1); // "Dmolar"
    if (!is_valid_parameter(den, iWrt2)){return false;}
    
    // If we haven't quit yet, all is well
    return true;
}
bool is_valid_first_saturation_derivative(const std::string &name, parameters &iOf, parameters &iWrt)
{
    if (get_debug_level() > 5){ std::cout << format("is_valid_first_saturation_derivative(%s)", name.c_str()); }
    // There should be exactly one /
    // There should be exactly one |

    // Suppose we start with "d(P)/d(T)|sigma"
    std::vector<std::string> split_at_bar = strsplit(name, '|'); // "d(P)/d(T)"  and "sigma"
    if (split_at_bar.size() != 2){ return false; }

    std::vector<std::string> split_at_slash = strsplit(split_at_bar[0], '/'); // "d(P)" and "d(T)"
    if (split_at_slash.size() != 2){ return false; }

    std::size_t i0 = split_at_slash[0].find("(");
    std::size_t i1 = split_at_slash[0].find(")", i0);
    if (!((i0 > 0) && (i0 != std::string::npos) && (i1 > (i0+1)) && (i1 != std::string::npos))){ return false; }
    std::string num = split_at_slash[0].substr(i0+1, i1-i0-1);

    i0 = split_at_slash[1].find("(");
    i1 = split_at_slash[1].find(")", i0);
    if (!((i0 > 0) && (i0 != std::string::npos) && (i1 > (i0+1)) && (i1 != std::string::npos))){ return false; }
    std::string den = split_at_slash[1].substr(i0+1, i1-i0-1);

    parameters Of, Wrt;
    if (is_valid_parameter(num, Of) && is_valid_parameter(den, Wrt) && upper(split_at_bar[1]) == "SIGMA"){
        iOf = Of; iWrt = Wrt; return true;
    }
    else{
        return false;
    }
}
static int level_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	unsigned int val;

	switch (cmd) {
		case LEVEL_DEV_UNSET_UPLOAD:
			printk("fake_level: %s LEVEL_DEV_UNSET_UPLOAD", __func__);
			//kernel_sec_clear_upload_magic_number();
			return 0;

		case LEVEL_DEV_SET_AUTOTEST:
			printk("fake_level: %s LEVEL_DEV_SET_AUTOTEST", __func__);
			//kernel_sec_set_autotest();
			return 0;

		case LEVEL_DEV_SET_DEBUGLEVEL:
			printk("fake_level: %s LEVEL_DEV_SET_DEBUGLEVEL", __func__);
			//set_debug_level();
			return 0;
			
		case LEVEL_DEV_GET_DEBUGLEVEL:
		{
			val = get_debug_level();
			return copy_to_user((unsigned int *)arg, &val, sizeof(val));
		}
		default:
			printk("Unknown Cmd: %x\n", cmd);
			break;
		}
	return -ENOTSUPP;
}
Exemple #10
0
double convert_from_kSI_to_SI(long iInput, double value)
{
    if (get_debug_level() > 8){
        std::cout << format("%s:%d: convert_from_kSI_to_SI(i=%d,value=%g)\n",__FILE__,__LINE__,iInput,value).c_str();
    }

    switch (iInput)
    {
    case CoolProp::iP:
    case CoolProp::iCpmass:
    case CoolProp::iCp0mass:
    case CoolProp::iSmass:
    case CoolProp::iGmass:
    case CoolProp::iCvmass:
    case CoolProp::iHmass:
    case CoolProp::iUmass:
    case CoolProp::iconductivity:
        return value*1000.0;
    case CoolProp::iDmass:
    case CoolProp::ispeed_sound:
    case CoolProp::iQ:
    case CoolProp::iviscosity:
    case CoolProp::iT:
    case CoolProp::iPrandtl:
    case CoolProp::isurface_tension:
        return value;
    default:
        throw CoolProp::ValueError(format("index [%d] is invalid in convert_from_kSI_to_SI",iInput).c_str());
    }
}
Exemple #11
0
std::vector<std::vector<double> > PropsSImulti(const std::vector<std::string> &Outputs,
                                               const std::string &Name1,
                                               const std::vector<double> &Prop1,
                                               const std::string &Name2,
                                               const std::vector<double> &Prop2,
                                               const std::string &backend,
                                               const std::vector<std::string> &fluids,
                                               const std::vector<double> &fractions)
{
    std::vector<std::vector<double> > IO;

    #if !defined(NO_ERROR_CATCHING)
    try{
    #endif

        // Call the subfunction that can bubble errors
        _PropsSImulti(Outputs, Name1, Prop1, Name2, Prop2, backend, fluids, fractions, IO);

        // Return the value(s)
        return IO;

    #if !defined(NO_ERROR_CATCHING)
    }
    catch(const std::exception& e){
        set_error_string(e.what());
        #if defined (PROPSSI_ERROR_STDOUT)
        std::cout << e.what() << std::endl;
        #endif
        if (get_debug_level() > 1){std::cout << e.what() << std::endl;}
    }
    catch(...){
    }
    #endif
    return std::vector<std::vector<double> >();
}
/**
@param volu_fractions The vector of volume fractions of the components
*/
void IncompressibleBackend::set_volu_fractions(const std::vector<long double> &volu_fractions){
	if (get_debug_level()>=10) std::cout << format("Incompressible backend: Called set_volu_fractions with %s ",vec_to_string(volu_fractions).c_str()) << std::endl;
	if (volu_fractions.size()!=1) throw ValueError(format("The incompressible backend only supports one entry in the volume fraction vector and not %d.",volu_fractions.size()));
	if (fluid->getxid()==IFRAC_PURE) {
		this->set_fractions(std::vector<long double>(1,0));
		if (get_debug_level()>=20) std::cout << format("Incompressible backend: Overwriting fractions for pure fluid with %s -> %s",vec_to_string(volu_fractions).c_str(),vec_to_string(this->_fractions).c_str()) << std::endl;
	} else if (fluid->getxid()==IFRAC_VOLUME) {
		this->set_fractions(volu_fractions);
	} else {
		std::vector<long double> tmp_fractions;
		for (std::size_t i = 0; i < volu_fractions.size(); i++) {
			tmp_fractions.push_back((long double) fluid->inputFromVolume(0.0, volu_fractions[i]));
	    }
		this->set_fractions(tmp_fractions);
	}
}
Exemple #13
0
void extract_backend(std::string fluid_string, std::string &backend, std::string &fluid)
{
    std::size_t i;
    // For backwards compatibility reasons, if "REFPROP-" or "REFPROP-MIX:" start
    // the fluid_string, replace them with "REFPROP::"
    if (fluid_string.find("REFPROP-MIX:") == 0)
    {
        fluid_string.replace(0, 12, "REFPROP::");
    }
    if (fluid_string.find("REFPROP-") == 0)
    {
        fluid_string.replace(0, 8, "REFPROP::");
    }
    if (has_backend_in_string(fluid_string, i))
    {
        // Part without the ::
        backend = fluid_string.substr(0, i);
        // Fluid name after the ::
        fluid = fluid_string.substr(i+2);
    }
    else
    {
        backend = "?";
        fluid = fluid_string;
    }
    if (get_debug_level()>10) std::cout << format("%s:%d: backend extracted. backend: %s. fluid: %s\n",__FILE__,__LINE__, backend.c_str(), fluid.c_str());
}
Exemple #14
0
void layout_image_lirc_init(LayoutWindow *lw)
{
    gint flags;
    gboolean lirc_verbose = (get_debug_level() >= 2);

    lirc_fd = lirc_init(GQ_APPNAME_LC, lirc_verbose);
    if (lirc_fd == -1)
    {
        DEBUG_1("Initializing LIRC... failed");
        return;
    }

    DEBUG_1("Initializing LIRC... OK");
    if (lirc_readconfig(NULL, &config, NULL) == -1)
    {
        lirc_deinit();

        g_fprintf(stderr,
                  _("could not read LIRC config file\n"
                    "please read the documentation of LIRC to \n"
                    "know how to create a proper config file\n"));
        fflush(stderr);

        DEBUG_1("Failed to read LIRC config file");
        return;
    }
    if (lirc_verbose) fflush(stderr);

    gio_chan = g_io_channel_unix_new(lirc_fd);
    input_tag = g_io_add_watch(gio_chan, G_IO_IN,
                               lirc_input_callback, lw);
    fcntl(lirc_fd, F_SETOWN, getpid());
    flags = fcntl(lirc_fd, F_GETFL, 0);
    if (flags != -1) fcntl(lirc_fd, F_SETFL, flags|O_NONBLOCK);
}
Exemple #15
0
void _PropsSI_initialize(const std::string &backend,
                         const std::vector<std::string> &fluid_names,
                         const std::vector<double> &z,
                         shared_ptr<AbstractState> &State){

    if (fluid_names.empty()){throw ValueError("fluid_names cannot be empty");}

    std::vector<double> fractions(1, 1.0); // Default to one component, unity fraction
    const std::vector<double> *fractions_ptr = NULL; // Pointer to the array to be used;

    if (fluid_names.size() > 1){
        // Set the pointer - we are going to use the supplied fractions; they must be provided
        fractions_ptr = &z;
        // Reset the state
        State.reset(AbstractState::factory(backend, fluid_names));
    }
    else if (fluid_names.size() == 1){
        if (has_fractions_in_string(fluid_names[0]) || has_solution_concentration(fluid_names[0])){
            // Extract fractions from the string
            std::string fluid_string = extract_fractions(fluid_names[0], fractions);
            // Set the pointer - we are going to use the extracted fractions
            fractions_ptr = &fractions;
            // Reset the state
            State.reset(AbstractState::factory(backend, fluid_string));
        }
        else{
            if (z.empty()){
                // Set the pointer - we are going to use the default fractions
                fractions_ptr = &fractions;
            }
            else{
                // Set the pointer - we are going to use the provided fractions
                fractions_ptr = &z;
            }
            // Reset the state
            State.reset(AbstractState::factory(backend, fluid_names));
        }
    }
    else { // The only path where fractions_ptr stays NULL
      throw ValueError("fractions_ptr is NULL");
    }
    if (!State->available_in_high_level()){
        throw ValueError("This AbstractState derived class cannot be used in the high-level interface; see www.coolprop.org/dev/coolprop/LowLevelAPI.html");
    }

    // Set the fraction for the state
    if (State->using_mole_fractions()){
        // If a predefined mixture or a pure fluid, the fractions will already be set
        if (State->get_mole_fractions().empty()){
            State->set_mole_fractions(*fractions_ptr);
        }
    } else if (State->using_mass_fractions()){
        State->set_mass_fractions(*fractions_ptr);
    } else if (State->using_volu_fractions()){
        State->set_volu_fractions(*fractions_ptr);
    } else {
        if (get_debug_level()>50) std::cout << format("%s:%d: _PropsSI, could not set composition to %s, defaulting to mole fraction.\n",__FILE__,__LINE__, vec_to_string(z).c_str()).c_str();
    }
}
oph_job_info *oph_find_workflow_in_job_list_to_drop(oph_job_list * list, const char *sessionid, int workflowid, oph_job_info ** prev)
{
	if (!list)
		return 0;
	if (prev)
		*prev = NULL;
	oph_job_info *temp, *temp_prev = NULL, *next, *result = NULL;
	struct timeval tv;
	gettimeofday(&tv, NULL);
	int remote_deadline = tv.tv_sec - oph_server_workflow_timeout;
#ifdef PRINT_RAW_SHARED_MEMORY
	int i, j;
#endif
	for (temp = list->head; temp; temp_prev = temp, temp = next) {
		next = temp->next;
		if (temp->timestamp < remote_deadline) {
			if (!list->counter)
				return NULL;
			if (list->tail == temp)
				list->tail = temp_prev;
			if (list->head == temp)
				list->head = next;
			else if (temp_prev)
				temp_prev->next = next;
			list->counter--;

			if (temp->wf->exec_mode && !strncasecmp(temp->wf->exec_mode, OPH_ARG_MODE_SYNC, OPH_MAX_STRING_SIZE)) {
				temp->wf->status = OPH_ODB_STATUS_EXPIRED;
				pthread_cond_broadcast(&termination_flag);
			} else
				oph_workflow_free(temp->wf);

			free(temp);
		} else if ((temp->wf->workflowid == workflowid) && (!sessionid || !strcmp(temp->wf->sessionid, sessionid)))
#ifdef PRINT_RAW_SHARED_MEMORY
			if (!result)
				result = temp;

		if (get_debug_level() == LOG_DEBUG) {
			printf("Workflow '%s': ID %d STATUS %d\n", temp->wf->name, temp->wf->workflowid, temp->wf->status);
			for (i = 0; i < temp->wf->tasks_num; ++i) {
				printf("\tTask %d '%s': ID %d#%d STATUS %d OPERATOR %s\n", i, temp->wf->tasks[i].name, temp->wf->workflowid, temp->wf->tasks[i].markerid, temp->wf->tasks[i].status,
				       temp->wf->tasks[i].operator);
				for (j = 0; j < temp->wf->tasks[i].light_tasks_num; ++j)
					printf("\t\tLight task %d: ID %d#%d STATUS %d\n", j, temp->wf->workflowid, temp->wf->tasks[i].light_tasks[j].markerid,
					       temp->wf->tasks[i].light_tasks[j].status);
			}
		}

		if (prev && !result)
			*prev = temp;
#else
			return temp;
		if (prev)
			*prev = temp;
#endif
	}
	return result;
}
Exemple #17
0
void logmsg( FILE* logfile, const char* fmt, ... ) {
   if( get_debug_level() == 0 )
      return;
   
   if( logfile ) {
      va_list args;
   
      va_start(args, fmt);
      vfprintf(logfile, fmt, args);
      va_end(args);
   }
   
   if( get_debug_level() > 0 ) {
      va_list args;
      va_start( args, fmt );
      vprintf(fmt, args);
      fflush(stdout);
      va_end(args);
   }
}
static ssize_t show_control(struct device *d,
		struct device_attribute *attr, char *buf)
{
	char *p = buf;
	unsigned int val;

	val = get_debug_level();
	
	p += sprintf(p, "0x%4x\n",val);

	return p - buf;
}
Exemple #19
0
double PropsSI(const std::string &Output, const std::string &Name1, double Prop1, const std::string &Name2, double Prop2, const std::string &Ref)
{
    #if !defined(NO_ERROR_CATCHING)
    try{
    #endif

        // BEGIN OF TRY
        // Here is the real code that is inside the try block
    

        std::string backend, fluid;
        extract_backend(Ref, backend, fluid);
        std::vector<double> fractions(1, 1.0);
        // extract_fractions checks for has_fractions_in_string / has_solution_concentration; no need to double check
        std::string fluid_string = extract_fractions(fluid, fractions);
        std::vector<std::vector<double> > IO;
        _PropsSImulti(strsplit(Output,'&'), Name1, std::vector<double>(1, Prop1), Name2, std::vector<double>(1, Prop2), backend, strsplit(fluid_string, '&'), fractions, IO);
        if (IO.empty()){ throw ValueError(get_global_param_string("errstring").c_str()); }
        if (IO.size()!= 1 || IO[0].size() != 1){ throw ValueError(format("output should be 1x1; error was %s", get_global_param_string("errstring").c_str())); }

        double val = IO[0][0];

        if (get_debug_level() > 1){ std::cout << format("_PropsSI will return %g",val) << std::endl; }
        return val;
        // END OF TRY
    #if !defined(NO_ERROR_CATCHING)
    }
    catch(const std::exception& e){
        set_error_string(e.what() + format(" : PropsSI(\"%s\",\"%s\",%0.10g,\"%s\",%0.10g,\"%s\")",Output.c_str(),Name1.c_str(), Prop1, Name2.c_str(), Prop2, Ref.c_str()));
        #if defined (PROPSSI_ERROR_STDOUT)
        std::cout << e.what() << std::endl;
        #endif
        if (get_debug_level() > 1){std::cout << e.what() << std::endl;}
        return _HUGE;
    }
    catch(...){
        return _HUGE;
    }
    #endif
}
Exemple #20
0
void rrd_init()
{
	debuglogger(DEBUG_GLOBAL + DEBUG_RRD, LEVEL_INFO, NULL, "Initializing RRDTOOL pipe.");
	string rrdtool = get_setting(setPathRRDTOOL) + " - ";
	if (!(get_debug_components() & DEBUG_RRD) || !(get_debug_level() & LEVEL_DEBUG))
		rrdtool = rrdtool + " >/dev/null";
	rrdtool_pipe = popen(rrdtool.c_str(), "w");
	if (!rrdtool_pipe)
	{
		debuglogger(DEBUG_GLOBAL + DEBUG_RRD, LEVEL_CRITICAL, NULL, "Failed to initialize RRDTOOL pipe.");
		exit(3);
	}
		
	// sets buffering to one line
	setlinebuf(rrdtool_pipe);
}
Exemple #21
0
int logerr( FILE* logfile, const char* fmt, ... ) {
   int ret = -errno;
   
   if( logfile ) {
      va_list args;
      
      va_start(args, fmt);
      vfprintf(logfile, fmt, args);
      va_end(args);
   }
   if( get_debug_level() > 0 ) {
      va_list args;
      
      va_start(args, fmt);
      vfprintf(stderr, fmt, args);
      fflush(stderr);
      va_end(args);
   }
   return ret;
}
Exemple #22
0
int client_launch_exec (int forkit, char *dir, char* argv[], struct server *s) {
	int pid;
	int pipefds[2];
	int flags;
	char msg[CLIENT_ERROR_BUFFER];

	if (get_debug_level() || dontlaunch) {
		char* cmdline = g_strjoinv(" # ",argv);
		debug(0,"%s",cmdline);
		g_free(cmdline);
	}

	if (dontlaunch)
		return -1;

	script_action_gamestart(NULL, s);

	if (forkit) {

		if (pipe (pipefds) < 0) {
			dialog_failed ("pipe", NULL);
			return -1;
		}

		pid = fork ();

		if (pid == -1) {
			dialog_failed ("fork", NULL);
			return -1;
		}

		if (pid) {  /* parent */
			close (pipefds[1]);

			flags = fcntl (pipefds[0], F_GETFL, 0);
			if (flags < 0 || fcntl (pipefds[0], F_SETFL, flags | O_NONBLOCK) < 0) {
				dialog_failed ("fcntl", NULL);
				return -1;
			}

			client_attach (pid, pipefds[0], s);
		}
		else {      /* child */

			close_fds(pipefds[1]);

			if (dir && dir[0] != '\0') {
				if (chdir (dir) != 0) {
					g_snprintf (msg, CLIENT_ERROR_BUFFER, "%schdir failed: %s", 
							CLIENT_ERROR_MSG_HEAD, g_strerror (errno));
					goto error_out;
				}
			}


			server_set_env(s);

			execvp (argv[0], argv);

			g_snprintf (msg, CLIENT_ERROR_BUFFER, "%sexec(%s) failed: %s", 
					CLIENT_ERROR_MSG_HEAD, argv[0], g_strerror (errno));

			error_out:
			write (pipefds[1], msg, strlen (msg) + 1);
			close (pipefds[1]);

			on_sig (SIGHUP,  _exit);
			on_sig (SIGINT,  _exit);
			on_sig (SIGQUIT, _exit);
			on_sig (SIGBUS,  _exit);
			on_sig (SIGSEGV, _exit);
			on_sig (SIGPIPE, _exit);
			on_sig (SIGTERM, _exit);
			on_sig (SIGALRM, _exit);
			on_sig (SIGCHLD, SIG_DFL);

			_exit (1);
		}
		return pid;
	}

	execvp (argv[0], argv);

	dialog_failed ("exec", argv[0]);
	return -1;
}
Exemple #23
0
// Make this a wrapped function so that error bubbling can be done properly
double _Props(std::string Output, std::string Name1, double Prop1, std::string Name2, double Prop2, std::string Ref)
{
	if (get_debug_level()>5){
		std::cout<<__FILE__<<": "<<Output.c_str()<<","<<Name1.c_str()<<","<<Prop1<<","<<Name2.c_str()<<","<<Prop2<<","<<Ref.c_str()<<std::endl;
	}
	/* 
    If the fluid name is not actually a refrigerant name, but a string beginning with "REFPROP-",
    then REFPROP is used to calculate the desired property.
    */
    if (IsREFPROP(Ref))  // First eight characters match "REFPROP-"
    {
        // Stop here if there is no REFPROP support
    	if (REFPROPFluidClass::refpropSupported()) {
			return REFPROP(Output,Name1,Prop1,Name2,Prop2,Ref);
    	} else {
    		throw AttributeError(format("Your refrigerant [%s] is from REFPROP, but CoolProp does not support REFPROP on this platform, yet.",Ref.c_str()));
    		return -_HUGE;
    	}
    }
	else if (IsCoolPropFluid(Ref))
	{
		pFluid = Fluids.get_fluid(Ref);
		// Convert all the parameters to integers
		long iOutput = get_param_index(Output);
		if (iOutput<0) 
			throw ValueError(format("Your output key [%s] is not valid. (names are case sensitive)",Output.c_str()));
		long iName1 = get_param_index(std::string(Name1));  
		if (iName1<0) 
			throw ValueError(format("Your input key #1 [%s] is not valid. (names are case sensitive)",Name1.c_str()));
		long iName2 = get_param_index(std::string(Name2));  
		if (iName2<0) 
			throw ValueError(format("Your input key #2 [%s] is not valid. (names are case sensitive)",Name2.c_str()));
		// Call the internal method that uses the parameters converted to longs
		return _CoolProp_Fluid_Props(iOutput,iName1,Prop1,iName2,Prop2,pFluid);
	}
    

    // It's a brine, call the brine routine
	else if (IsBrine((char*)Ref.c_str()))
    {
		//Enthalpy and pressure are the inputs
		if ((Name1.c_str()[0]=='H' && Name2.c_str()[0]=='P') || (Name2.c_str()[0]=='H' && Name1.c_str()[0]=='P'))
        {
			if (Name2.c_str()[0]=='H' && Name1.c_str()[0]=='P')
			{
				std::swap(Prop1,Prop2);
				std::swap(Name1,Name2);
			}
			// Start with a guess of 10 K below max temp of fluid
			double Tguess = SecFluids('M',Prop1,Prop2,(char*)Ref.c_str())-10;
			// Solve for the temperature
			double T =_T_hp_secant(Ref,Prop1,Prop2,Tguess);
			// Return whatever property is desired
			return SecFluids(Output[0],T,Prop2,(char*)Ref.c_str());
		}
		else if ((Name1.c_str()[0] == 'T' && Name2.c_str()[0] =='P') || (Name1.c_str()[0] == 'P' && Name2.c_str()[0] == 'T'))
        {
			if (Name1.c_str()[0] =='P' && Name2.c_str()[0] =='T'){
				std::swap(Prop1,Prop2);
			}
			return SecFluids(Output[0],Prop1,Prop2,(char*)Ref.c_str());
		}
		else
		{
			throw ValueError("For brine, inputs must be (order doesnt matter) 'T' and 'P', or 'H' and 'P'");
		}
    }
	// It's an incompressible liquid, call the routine
	else if (IsIncompressibleLiquid((char*)Ref.c_str()))
    {
		//Enthalpy and pressure are the inputs
		if ((Name1.c_str()[0]=='H' && Name2.c_str()[0]=='P') || (Name2.c_str()[0]=='H' && Name1.c_str()[0]=='P'))
        {
			if (Name2.c_str()[0]=='H' && Name1.c_str()[0]=='P')
			{
				std::swap(Prop1,Prop2);
				std::swap(Name1,Name2);
			}
			
			// Solve for the temperature
			double T =_T_hp_secant(Ref,Prop1,Prop2,300);
			// Return whatever property is desired
			return IncompLiquid(get_param_index(Output),T,Prop2,(char*)Ref.c_str());
		}
		else if ((Name1.c_str()[0] == 'T' && Name2.c_str()[0] =='P') || (Name1.c_str()[0] == 'P' && Name2.c_str()[0] == 'T'))
        {
			if (Name1.c_str()[0] =='P' && Name2.c_str()[0] =='T'){
				std::swap(Prop1,Prop2);
			}
			return IncompLiquid(get_param_index(Output),Prop1,Prop2,Ref);
		}
		else
		{
			throw ValueError("For brine, inputs must be (order doesnt matter) 'T' and 'P', or 'H' and 'P'");
		}
    }
	else
	{
		throw ValueError(format("Your fluid name [%s] is not a CoolProp fluid, a REFPROP fluid, a brine or a liquid",Ref.c_str()));
	}
}
Exemple #24
0
// Internal function to do the actual calculations, make this a wrapped function so
// that error bubbling can be done properly
double _PropsSI(const std::string &Output, const std::string &Name1, double Prop1, const std::string &Name2, double Prop2, const std::string &backend, const std::string &Ref, const std::vector<double> &z)
{
    parameters iOutput = iundefined_parameter;
    parameters iOf = iundefined_parameter, iWrt = iundefined_parameter, iConstant = iundefined_parameter, 
               iOf1 = iundefined_parameter, iWrt1 = iundefined_parameter, iConstant1 = iundefined_parameter, 
               iWrt2 = iundefined_parameter, iConstant2 = iundefined_parameter;
    double x1, x2;
	
    if (get_debug_level()>5){
        std::cout << format("%s:%d: _PropsSI(%s,%s,%g,%s,%g,%s,%s)\n",__FILE__,__LINE__,Output.c_str(),Name1.c_str(),Prop1,Name2.c_str(),Prop2,backend.c_str(),Ref.c_str(), vec_to_string(z).c_str()).c_str();
    }

    // The state we are going to use
    shared_ptr<AbstractState> State;
    
	// If the fractions of the components have been encoded in the string, extract them
	// If they have not, this function does nothing
	std::vector<double> fractions;
	if (z.empty())
	{
		// Make a one-element vector
		fractions = std::vector<double>(1, 1);
	}
	else{
		// Make a copy
		fractions = z;
	}
	
	std::string fluid_string = extract_fractions(Ref, fractions);
	
	// We are going to let the factory function load the state
	State.reset(AbstractState::factory(backend, fluid_string));
    
	// First check if it is a trivial input (critical/max parameters for instance)
	if (is_valid_parameter(Output, iOutput) && is_trivial_parameter(iOutput))
	{
		double val = State->trivial_keyed_output(iOutput);
		return val;
	}
	
	long iName1 = get_parameter_index(Name1);
	long iName2 = get_parameter_index(Name2);

	if (State->using_mole_fractions()){
		State->set_mole_fractions(fractions);
	} else if (State->using_mass_fractions()){
		State->set_mass_fractions(fractions);
	} else if (State->using_volu_fractions()){
		State->set_volu_fractions(fractions);
	} else {
		if (get_debug_level()>50) std::cout << format("%s:%d: _PropsSI, could not set composition to %s, defaulting to mole fraction.\n",__FILE__,__LINE__, vec_to_string(z).c_str()).c_str();
	}

	// Obtain the input pair
	CoolProp::input_pairs pair = generate_update_pair(iName1, Prop1, iName2, Prop2, x1, x2);

	// Update the state
	State->update(pair, x1, x2);
    
    if (iOutput != iundefined_parameter){
        // Get the desired output
        double val = State->keyed_output(iOutput);
        
        // Return the value
        return val;
    }
    else if (is_valid_first_derivative(Output, iOf, iWrt, iConstant)){
        // Return the desired output
        double val = State->first_partial_deriv(iOf, iWrt, iConstant);
        
        // Return the value
        return val;
    }
    else if (is_valid_second_derivative(Output, iOf1, iWrt1, iConstant1, iWrt2, iConstant2)){
        // Return the desired output
        double val = State->second_partial_deriv(iOf1, iWrt1, iConstant1, iWrt2, iConstant2);
        
        // Return the value
        return val;
    }
    else{
        throw ValueError(format("Output [%s] is not a parameter or a string representation of a derivative",Output.c_str()).c_str());
    }
}
Exemple #25
0
bool
pkcs11_initialize(
    const bool protected_auth,
    const int nPINCachePeriod
    ) {
    CK_RV rv = CKR_FUNCTION_FAILED;

    dmsg(
        D_PKCS11_DEBUG,
        "PKCS#11: pkcs11_initialize - entered"
        );

    if ((rv = pkcs11h_engine_setSystem(&s_pkcs11h_sys_engine)) != CKR_OK)
    {
        msg(M_FATAL, "PKCS#11: Cannot initialize system engine %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if ((rv = pkcs11h_initialize()) != CKR_OK)
    {
        msg(M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if ((rv = pkcs11h_setLogHook(_pkcs11_openvpn_log, NULL)) != CKR_OK)
    {
        msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    pkcs11h_setLogLevel(_pkcs11_msg_openvpn2pkcs11(get_debug_level()));

    if ((rv = pkcs11h_setForkMode(TRUE)) != CKR_OK)
    {
        msg(M_FATAL, "PKCS#11: Cannot set fork mode %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if ((rv = pkcs11h_setTokenPromptHook(_pkcs11_openvpn_token_prompt, NULL)) != CKR_OK)
    {
        msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_pin_prompt, NULL)) != CKR_OK)
    {
        msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if ((rv = pkcs11h_setProtectedAuthentication(protected_auth)) != CKR_OK)
    {
        msg(M_FATAL, "PKCS#11: Cannot set protected authentication mode %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if ((rv = pkcs11h_setPINCachePeriod(nPINCachePeriod)) != CKR_OK)
    {
        msg(M_FATAL, "PKCS#11: Cannot set Pcache period %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    rv = CKR_OK;

cleanup:
    dmsg(
        D_PKCS11_DEBUG,
        "PKCS#11: pkcs11_initialize - return %ld-'%s'",
        rv,
        pkcs11h_getMessage(rv)
        );

    return rv == CKR_OK;
}
Exemple #26
0
std::string extract_fractions(const std::string &fluid_string, std::vector<double> &fractions)
{
    if (has_fractions_in_string(fluid_string))
    {
        fractions.clear();
        std::vector<std::string> names;

        // Break up into pairs - like "Ethane[0.5]&Methane[0.5]" -> ("Ethane[0.5]","Methane[0.5]")
        std::vector<std::string> pairs = strsplit(fluid_string, '&');

        for (std::size_t i = 0; i < pairs.size(); ++i)
        {
            const std::string &fluid = pairs[i];

            // Must end with ']'
            if (fluid[fluid.size()-1] != ']')
                throw ValueError(format("Fluid entry [%s] must end with ']' character",pairs[i].c_str()));

            // Split at '[', but first remove the ']' from the end by taking a substring
            std::vector<std::string> name_fraction = strsplit(fluid.substr(0, fluid.size()-1), '[');

            if (name_fraction.size() != 2){throw ValueError(format("Could not break [%s] into name/fraction", fluid.substr(0, fluid.size()-1).c_str()));}

            // Convert fraction to a double
            char *pEnd;
            const std::string &name = name_fraction[0], &fraction = name_fraction[1];
            double f = strtod(fraction.c_str(), &pEnd);

            // If pEnd points to the last character in the string, it wasn't able to do the conversion
            if (pEnd == &(fraction[fraction.size()-1])){throw ValueError(format("Could not convert [%s] into number", fraction.c_str()));}

            // And add to vector
            fractions.push_back(f);

            // Add name
            names.push_back(name);
        }

        if (get_debug_level()>10) std::cout << format("%s:%d: Detected fractions of %s for %s.",__FILE__,__LINE__,vec_to_string(fractions).c_str(), (strjoin(names, "&")).c_str());
        // Join fluids back together
        return strjoin(names, "&");
    }
    else if (has_solution_concentration(fluid_string))
    {
        fractions.clear();
        double x;

        std::vector<std::string> fluid_parts = strsplit(fluid_string,'-');
        // Check it worked
        if (fluid_parts.size() != 2){
            throw ValueError(format("Format of incompressible solution string [%s] is invalid, should be like \"EG-20%\" or \"EG-0.2\" ", fluid_string.c_str()) );
        }

        // Convert the concentration into a string
        char* pEnd;
        x = strtod(fluid_parts[1].c_str(), &pEnd);

        // Check if per cent or fraction syntax is used
        if (!strcmp(pEnd,"%")){    x *= 0.01;}
        fractions.push_back(x);
        if (get_debug_level()>10) std::cout << format("%s:%d: Detected incompressible concentration of %s for %s.",__FILE__,__LINE__,vec_to_string(fractions).c_str(), fluid_parts[0].c_str());
        return fluid_parts[0];
    }
    else
    {
        return fluid_string;
    }
}
Exemple #27
0
void
show_pkcs11_ids(
    const char *const provider,
    bool cert_private
    ) {
    struct gc_arena gc = gc_new();
    pkcs11h_certificate_id_list_t user_certificates = NULL;
    pkcs11h_certificate_id_list_t current = NULL;
    CK_RV rv = CKR_FUNCTION_FAILED;

    if ((rv = pkcs11h_initialize()) != CKR_OK)
    {
        msg(M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if ((rv = pkcs11h_setLogHook(_pkcs11_openvpn_log, NULL)) != CKR_OK)
    {
        msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    pkcs11h_setLogLevel(_pkcs11_msg_openvpn2pkcs11(get_debug_level()));

    if ((rv = pkcs11h_setProtectedAuthentication(TRUE)) != CKR_OK)
    {
        msg(M_FATAL, "PKCS#11: Cannot set protected authentication %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_show_pkcs11_ids_pin_prompt, NULL)) != CKR_OK)
    {
        msg(M_FATAL, "PKCS#11: Cannot set PIN hook %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if (
        (rv = pkcs11h_addProvider(
             provider,
             provider,
             TRUE,
             0,
             FALSE,
             0,
             cert_private ? TRUE : FALSE
             )) != CKR_OK
        )
    {
        msg(M_FATAL, "PKCS#11: Cannot add provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    if (
        (rv = pkcs11h_certificate_enumCertificateIds(
             PKCS11H_ENUM_METHOD_CACHE_EXIST,
             NULL,
             PKCS11H_PROMPT_MASK_ALLOW_ALL,
             NULL,
             &user_certificates
             )) != CKR_OK
        )
    {
        msg(M_FATAL, "PKCS#11: Cannot enumerate certificates %ld-'%s'", rv, pkcs11h_getMessage(rv));
        goto cleanup;
    }

    msg(
        M_INFO|M_NOPREFIX|M_NOLF,
        (
            "\n"
            "The following objects are available for use.\n"
            "Each object shown below may be used as parameter to\n"
            "--pkcs11-id option please remember to use single quote mark.\n"
        )
        );
    for (current = user_certificates; current != NULL; current = current->next) {
        pkcs11h_certificate_t certificate = NULL;
        char *dn = NULL;
        char serial[1024] = {0};
        char *ser = NULL;
        size_t ser_len = 0;

        if (
            (rv = pkcs11h_certificate_serializeCertificateId(
                 NULL,
                 &ser_len,
                 current->certificate_id
                 )) != CKR_OK
            )
        {
            msg(M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
            goto cleanup1;
        }

        if (
            rv == CKR_OK
            && (ser = (char *)malloc(ser_len)) == NULL
            )
        {
            msg(M_FATAL, "PKCS#11: Cannot allocate memory");
            goto cleanup1;
        }

        if (
            (rv = pkcs11h_certificate_serializeCertificateId(
                 ser,
                 &ser_len,
                 current->certificate_id
                 )) != CKR_OK
            )
        {
            msg(M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
            goto cleanup1;
        }

        if (
            (rv = pkcs11h_certificate_create(
                 current->certificate_id,
                 NULL,
                 PKCS11H_PROMPT_MASK_ALLOW_ALL,
                 PKCS11H_PIN_CACHE_INFINITE,
                 &certificate
                 ))
            )
        {
            msg(M_FATAL, "PKCS#11: Cannot create certificate %ld-'%s'", rv, pkcs11h_getMessage(rv));
            goto cleanup1;
        }

        if (
            (dn = pkcs11_certificate_dn(
                 certificate,
                 &gc
                 )) == NULL
            )
        {
            goto cleanup1;
        }

        if (
            (pkcs11_certificate_serial(
                 certificate,
                 serial,
                 sizeof(serial)
                 ))
            )
        {
            goto cleanup1;
        }

        msg(
            M_INFO|M_NOPREFIX|M_NOLF,
            (
                "\n"
                "Certificate\n"
                "       DN:             %s\n"
                "       Serial:         %s\n"
                "       Serialized id:  %s\n"
            ),
            dn,
            serial,
            ser
            );

cleanup1:

        if (certificate != NULL)
        {
            pkcs11h_certificate_freeCertificate(certificate);
            certificate = NULL;
        }

        if (ser != NULL)
        {
            free(ser);
            ser = NULL;
        }
    }

cleanup:
    if (user_certificates != NULL)
    {
        pkcs11h_certificate_freeCertificateIdList(user_certificates);
        user_certificates = NULL;
    }

    pkcs11h_terminate();
    gc_free(&gc);
}
Exemple #28
0
void _PropsSI_outputs(shared_ptr<AbstractState> &State,
	     			 const std::vector<output_parameter> &output_parameters,
		    		 CoolProp::input_pairs input_pair,
			    	 const std::vector<double> &in1,
			    	 const std::vector<double> &in2,
			    	 std::vector<std::vector<double> > &IO){

	// Check the inputs
	if (in1.size() != in2.size()){ throw ValueError(format("lengths of in1 [%d] and in2 [%d] are not the same", in1.size(), in2.size()));}
	bool one_input_one_output = (in1.size() == 1 && in2.size() == 1 && output_parameters.size() == 1);
    // If all trivial outputs, never do a state update
    bool all_trivial_outputs = true;
    for (std::size_t j = 0; j < output_parameters.size(); ++j){
        if (output_parameters[j].type != output_parameter::OUTPUT_TYPE_TRIVIAL){
            all_trivial_outputs = false;
        }
    }
    parameters p1, p2;
    // If all outputs are also inputs, never do a state update
    bool all_outputs_in_inputs = true;
    if (input_pair != INPUT_PAIR_INVALID){
        // Split the input pair into parameters
        split_input_pair(input_pair, p1, p2);
        // See if each parameter is in the output vector and is a normal type input
        for (std::size_t j = 0; j < output_parameters.size(); ++j){
            if (output_parameters[j].type != output_parameter::OUTPUT_TYPE_NORMAL){
                all_outputs_in_inputs = false; break;
            }
            if (!(output_parameters[j].Of1 == p1 || output_parameters[j].Of1 == p2)){
                all_outputs_in_inputs = false; break;
            }
        }
    }
    else{
        if (!all_trivial_outputs){
            throw ValueError(format("Input pair variable is invalid and output(s) are non-trivial; cannot do state update"));
        }
        all_outputs_in_inputs = false;
    }

	if (get_debug_level() > 100)
	{
	   std::cout << format("%s (%d): input pair = %d ",__FILE__,__LINE__, input_pair)          << std::endl;
	   std::cout << format("%s (%d): in1 = %s ",__FILE__,__LINE__, vec_to_string(in1).c_str()) << std::endl;
	   std::cout << format("%s (%d): in2 = %s ",__FILE__,__LINE__, vec_to_string(in2).c_str()) << std::endl;
	}

	// Resize the output matrix
    std::size_t N1 = std::max(static_cast<std::size_t>(1), in1.size());
    std::size_t N2 = std::max(static_cast<std::size_t>(1), output_parameters.size());
	IO.resize(N1, std::vector<double>(N2, _HUGE));

    // Throw an error if at the end, there were no successes
    bool success = false;

    if (get_debug_level() > 100)
    {
        std::cout << format("%s (%d): Iterating over %d input value pairs.",__FILE__,__LINE__,IO.size()) << std::endl;
    }
	// Iterate over the state variable inputs
	for (std::size_t i = 0; i < IO.size(); ++i){
		try{
            if (input_pair != INPUT_PAIR_INVALID && !all_trivial_outputs && !all_outputs_in_inputs){
                // Update the state since it is a valid set of inputs
                State->update(input_pair, in1[i], in2[i]);
            }
        }
        catch(...){
            if (one_input_one_output){IO.clear(); throw;} // Re-raise the exception since we want to bubble the error
            // All the outputs are filled with _HUGE; go to next input
            for (std::size_t j = 0; j < IO[i].size(); ++j){ IO[i][j] = _HUGE; }
            continue;
        }

        for (std::size_t j = 0; j < IO[i].size(); ++j){
            // If all the outputs are inputs, there is no need for a state input
            if (all_outputs_in_inputs){
                if (p1 == output_parameters[j].Of1){
                    IO[i][j] = in1[i]; success = true; continue;
                }
                else if (p2 == output_parameters[j].Of1){
                    IO[i][j] = in2[i]; success = true; continue;
                }
                else{
                    throw ValueError();
                }
            }
            try{
                const output_parameter &output = output_parameters[j];
                switch (output.type){
                    case output_parameter::OUTPUT_TYPE_TRIVIAL:
                    case output_parameter::OUTPUT_TYPE_NORMAL:
                        IO[i][j] = State->keyed_output(output.Of1); break;
                    case output_parameter::OUTPUT_TYPE_FIRST_DERIVATIVE:
                        IO[i][j] = State->first_partial_deriv(output.Of1, output.Wrt1, output.Constant1); break;
                    case output_parameter::OUTPUT_TYPE_FIRST_SATURATION_DERIVATIVE:
                        IO[i][j] = State->first_saturation_deriv(output.Of1, output.Wrt1); break;
                    case output_parameter::OUTPUT_TYPE_SECOND_DERIVATIVE:
                        IO[i][j] = State->second_partial_deriv(output.Of1, output.Wrt1, output.Constant1, output.Wrt2, output.Constant2); break;
                    default:
                        throw ValueError(format("")); break;
                }
                // At least one has succeeded
                success = true;
            }
            catch(...){
                if (one_input_one_output){IO.clear(); throw;} // Re-raise the exception since we want to bubble the error
                IO[i][j] = _HUGE;
            }
        }
	}
    if (success == false) { IO.clear(); throw ValueError(format("No outputs were able to be calculated"));}
}
Exemple #29
0
void CoolProp::BicubicBackend::update(CoolProp::input_pairs input_pair, double val1, double val2)
{
    if (get_debug_level() > 0){ std::cout << format("update(%s,%g,%g)\n", get_input_pair_short_desc(input_pair).c_str(), val1, val2); }
	// Clear cached values
	clear();

    // To start, set quality to value that is for single-phase
    _Q = -1000;

	// Flush the cached indices (set to large number)
    cached_single_phase_i = std::numeric_limits<std::size_t>::max(); 
    cached_single_phase_j = std::numeric_limits<std::size_t>::max();
    cached_saturation_iL = std::numeric_limits<std::size_t>::max(); 
    cached_saturation_iV = std::numeric_limits<std::size_t>::max();
    
    PureFluidSaturationTableData &pure_saturation = dataset->pure_saturation;
    PhaseEnvelopeData & phase_envelope = dataset->phase_envelope;
    SinglePhaseGriddedTableData &single_phase_logph = dataset->single_phase_logph;
    SinglePhaseGriddedTableData &single_phase_logpT = dataset->single_phase_logpT;

    switch(input_pair){
        case HmolarP_INPUTS:{
            _hmolar = val1; _p = val2;
            if (!single_phase_logph.native_inputs_are_in_range(_hmolar, _p)){
                // Use the AbstractState instance
                using_single_phase_table = false;
                if (get_debug_level() > 5){ std::cout << "inputs are not in range"; }
                throw ValueError(format("inputs are not in range, hmolar=%Lg, p=%Lg", static_cast<CoolPropDbl>(_hmolar), _p));
            }
            else{
                using_single_phase_table = true; // Use the table !
                std::size_t iL, iV, iclosest = 0;
                CoolPropDbl hL = 0, hV = 0;
                SimpleState closest_state;
                bool is_two_phase = false;
                // Phase is imposed, use it
                if (imposed_phase_index != iphase_not_imposed){
                    is_two_phase = (imposed_phase_index == iphase_twophase);
                }
                else{
                    if (is_mixture){
                        is_two_phase = PhaseEnvelopeRoutines::is_inside(phase_envelope, iP, _p, iHmolar, _hmolar, iclosest, closest_state);
                    }
                    else{
                        is_two_phase = pure_saturation.is_inside(iP, _p, iHmolar, _hmolar, iL, iV, hL, hV);
                    }
                }
                if ( is_two_phase )
                {
                    using_single_phase_table = false;
                    _Q = (static_cast<double>(_hmolar)-hL)/(hV-hL);
                    if(!is_in_closed_range(0.0,1.0,static_cast<double>(_Q))){
                        throw ValueError("vapor quality is not in (0,1)");
                    }
                    else{
                        cached_saturation_iL = iL; cached_saturation_iV = iV;
                        _phase = iphase_twophase;
                    }
                }
                else{
                    // Find and cache the indices i, j
                    selected_table = SELECTED_PH_TABLE;
					single_phase_logph.find_native_nearest_good_cell(_hmolar, _p, cached_single_phase_i, cached_single_phase_j);
                    CellCoeffs &cell = dataset->coeffs_ph[cached_single_phase_i][cached_single_phase_j];
                    if (!cell.valid()){
                        if (cell.has_valid_neighbor()){
                            // Get new good neighbor
                            cell.get_alternate(cached_single_phase_i, cached_single_phase_j);
                        }
                        else{
                            if (!cell.valid()){throw ValueError(format("Cell is invalid and has no good neighbors for hmolar = %g, p= %g",val1,val2));}
                        }
                    }
                    // Recalculate the phase
                    recalculate_singlephase_phase();
                }
            }
            break;
        }
        case HmassP_INPUTS:{
            update(HmolarP_INPUTS, val1 * AS->molar_mass(), val2); // H: [J/kg] * [kg/mol] -> [J/mol]
            return;
        }
        case PUmolar_INPUTS:
        case PSmolar_INPUTS:
        case DmolarP_INPUTS:{
            CoolPropDbl otherval; parameters otherkey;
            switch(input_pair){
                case PUmolar_INPUTS: _p = val1; _umolar = val2; otherval = val2; otherkey = iUmolar; break;
                case PSmolar_INPUTS: _p = val1; _smolar = val2; otherval = val2; otherkey = iSmolar; break;
                case DmolarP_INPUTS: _rhomolar = val1; _p = val2; otherval = val1; otherkey = iDmolar; break;
                default: throw ValueError("Bad (impossible) pair");
            }
            
            using_single_phase_table = true; // Use the table (or first guess is that it is single-phase)!
            std::size_t iL, iV;
            CoolPropDbl zL = 0, zV = 0;
            std::size_t iclosest = 0;
            SimpleState closest_state;
            bool is_two_phase = false;
            // Phase is imposed, use it
            if (imposed_phase_index != iphase_not_imposed){
                is_two_phase = (imposed_phase_index == iphase_twophase);
            }
            else{
                if (is_mixture){
                    is_two_phase = PhaseEnvelopeRoutines::is_inside(phase_envelope, iP, _p, otherkey, otherval, iclosest, closest_state);
                }
                else{
                    is_two_phase = pure_saturation.is_inside(iP, _p, otherkey, otherval, iL, iV, zL, zV);
                }
            }
            if ( is_two_phase ){
                using_single_phase_table = false;
                if (otherkey == iDmolar){
                    _Q = (1/otherval - 1/zL)/(1/zV - 1/zL);
                }
                else{
                    _Q = (otherval - zL)/(zV - zL);
                }
                if(!is_in_closed_range(0.0, 1.0, static_cast<double>(_Q))){
                    throw ValueError("vapor quality is not in (0,1)");
                }
                else{
                    cached_saturation_iL = iL; cached_saturation_iV = iV;
                }
                _phase = iphase_twophase;
            }
            else{
                // Find and cache the indices i, j
                selected_table = SELECTED_PH_TABLE;
                single_phase_logph.find_nearest_neighbor(iP, _p, otherkey, otherval, cached_single_phase_i, cached_single_phase_j);
                CellCoeffs &cell = dataset->coeffs_ph[cached_single_phase_i][cached_single_phase_j];
                if (!cell.valid()){
                    if (cell.has_valid_neighbor()){
                        // Get new good neighbor
                        cell.get_alternate(cached_single_phase_i, cached_single_phase_j);
                    }
                    else{
                        if (!cell.valid()){throw ValueError(format("Cell is invalid and has no good neighbors for p = %g Pa, T= %g K",val1,val2));}
                    }
                }
				// Now find hmolar given P, X for X in Hmolar, Smolar, Umolar
                invert_single_phase_x(single_phase_logph, dataset->coeffs_ph, otherkey, otherval, _p, cached_single_phase_i, cached_single_phase_j);
                // Recalculate the phase
                recalculate_singlephase_phase();
            }
            break;
        }
        case DmassP_INPUTS:{
            // Call again, but this time with molar units; D: [kg/m^3] / [kg/mol] -> [mol/m^3]
            update(DmassP_INPUTS, val1 / AS->molar_mass(), val2); return;
        }
        case PUmass_INPUTS:{
            // Call again, but this time with molar units; U: [J/kg] * [kg/mol] -> [J/mol]
            update(PUmolar_INPUTS, val1, val2*AS->molar_mass()); return;
        }
        case PSmass_INPUTS:{
            // Call again, but this time with molar units; S: [J/kg/K] * [kg/mol] -> [J/mol/K]
            update(PSmolar_INPUTS, val1, val2*AS->molar_mass()); return;
        }
	    case PT_INPUTS:{
            _p = val1; _T = val2;
            if (!single_phase_logpT.native_inputs_are_in_range(_T, _p)){
                // Use the AbstractState instance
                using_single_phase_table = false;
                if (get_debug_level() > 5){ std::cout << "inputs are not in range"; }
                throw ValueError(format("inputs are not in range, p=%g Pa, T=%g K", _p, _T));
            }
            else{
                using_single_phase_table = true; // Use the table !
                std::size_t iL = 0, iV = 0, iclosest = 0;
                CoolPropDbl TL = 0, TV = 0;
                SimpleState closest_state;
                bool is_two_phase = false;
                // Phase is imposed, use it
                if (imposed_phase_index != iphase_not_imposed){
                    is_two_phase = (imposed_phase_index == iphase_twophase);
                }
                else{
                    if (is_mixture){
                        is_two_phase = PhaseEnvelopeRoutines::is_inside(phase_envelope, iP, _p, iT, _T, iclosest, closest_state);
                    }
                    else{
                        is_two_phase = pure_saturation.is_inside(iP, _p, iT, _T, iL, iV, TL, TV);
                    }
                }
                if ( is_two_phase )
                {
                    using_single_phase_table = false;
                    throw ValueError(format("P,T with TTSE cannot be two-phase for now"));
                }
                else{
                    // Find and cache the indices i, j
                    selected_table = SELECTED_PT_TABLE;
					single_phase_logpT.find_native_nearest_good_cell(_T, _p, cached_single_phase_i, cached_single_phase_j);
                    CellCoeffs &cell = dataset->coeffs_pT[cached_single_phase_i][cached_single_phase_j];
                    if (!cell.valid()){
                        if (cell.has_valid_neighbor()){
                            // Get new good neighbor
                            cell.get_alternate(cached_single_phase_i, cached_single_phase_j);
                        }
                        else{
                            if (!cell.valid()){throw ValueError(format("Cell is invalid and has no good neighbors for p = %g Pa, T= %g K",val1,val2));}
                        }
                    }

                    // If p < pc, you might be getting a liquid solution when you want a vapor solution or vice versa
                    // if you are very close to the saturation curve, so we figure out what the saturation temperature
                    // is for the given pressure
                    if (_p < this->AS->p_critical())
                    {
                        double Ts = pure_saturation.evaluate(iT, _p, _Q, iL, iV);
                        double TL = single_phase_logpT.T[cached_single_phase_i][cached_single_phase_j];
                        double TR = single_phase_logpT.T[cached_single_phase_i+1][cached_single_phase_j];
                        if (TL < Ts && Ts < TR){
                            if (_T < Ts){
                                if (cached_single_phase_i == 0){throw ValueError(format("P, T are near saturation, but cannot move the cell to the left")); }
                                // It's liquid, move the cell to the left
                                cached_single_phase_i--;
                            }else{
                                if (cached_single_phase_i > single_phase_logpT.Nx-2){ throw ValueError(format("P,T are near saturation, but cannot move the cell to the right")); }
                                // It's vapor, move to the right
                                cached_single_phase_i++;
                            }
                        }
                    }   
                    // Recalculate the phase
                    recalculate_singlephase_phase();
                }
            }
            break;
        }
        case DmassT_INPUTS:{
            // Call again, but this time with molar units; D: [kg/m^3] / [kg/mol] -> [mol/m^3]
            update(DmolarT_INPUTS, val1 / AS->molar_mass(), val2); return;
        }
        case SmassT_INPUTS:{
            // Call again, but this time with molar units; S: [J/kg/K] * [kg/mol] -> [J/mol/K]
            update(SmolarT_INPUTS, val1*AS->molar_mass(), val2); return;
        }
        case SmolarT_INPUTS:
        case DmolarT_INPUTS:{
            CoolPropDbl otherval; parameters otherkey;
            switch(input_pair){
                case SmolarT_INPUTS: _smolar = val1; _T = val2; otherval = val1; otherkey = iSmolar; break;
                case DmolarT_INPUTS: _rhomolar = val1; _T = val2; otherval = val1; otherkey = iDmolar; break;
                default: throw ValueError("Bad (impossible) pair");
            }
            
            using_single_phase_table = true; // Use the table (or first guess is that it is single-phase)!
            std::size_t iL, iV;
            CoolPropDbl zL = 0, zV = 0;
            std::size_t iclosest = 0;
            SimpleState closest_state;
            bool is_two_phase = false;
            // Phase is imposed, use it
            if (imposed_phase_index != iphase_not_imposed){
                is_two_phase = (imposed_phase_index == iphase_twophase);
            }
            else{
                if (is_mixture){
                    is_two_phase = PhaseEnvelopeRoutines::is_inside(phase_envelope, iT, _T, otherkey, otherval, iclosest, closest_state);
                }
                else{
                    is_two_phase = pure_saturation.is_inside(iT, _T, otherkey, otherval, iL, iV, zL, zV);
                }
            }
            if ( is_two_phase )
            {
                using_single_phase_table = false;
                if (otherkey == iDmolar){
                    _Q = (1/otherval - 1/zL)/(1/zV - 1/zL);
                }
                else{
                    _Q = (otherval - zL)/(zV - zL);
                }
                if(!is_in_closed_range(0.0, 1.0, static_cast<double>(_Q))){
                    throw ValueError("vapor quality is not in (0,1)");
                }
                else{
                    cached_saturation_iL = iL; cached_saturation_iV = iV;
                }
                _p = pure_saturation.evaluate(iP, _T, _Q, iL, iV);
            }
            else{
                // Find and cache the indices i, j
                selected_table = SELECTED_PT_TABLE;
                single_phase_logpT.find_nearest_neighbor(iT, _T, otherkey, otherval, cached_single_phase_i, cached_single_phase_j);
                CellCoeffs &cell = dataset->coeffs_pT[cached_single_phase_i][cached_single_phase_j];
                if (!cell.valid()){
                    if (cell.has_valid_neighbor()){
                        // Get new good neighbor
                        cell.get_alternate(cached_single_phase_i, cached_single_phase_j);
                    }
                    else{
                        if (!cell.valid()){throw ValueError(format("Cell is invalid and has no good neighbors for p = %g Pa, T= %g K",val1,val2));}
                    }
                }
				// Now find the y variable (Dmolar or Smolar in this case)
                invert_single_phase_y(single_phase_logpT, dataset->coeffs_pT, otherkey, otherval, _T, cached_single_phase_i, cached_single_phase_j);
                // Recalculate the phase
                recalculate_singlephase_phase();
            }
            break;
        }
        case PQ_INPUTS:{
            std::size_t iL = 0, iV = 0;
            _p = val1; _Q = val2;
            using_single_phase_table = false;
            if (!is_in_closed_range(0.0, 1.0, static_cast<double>(_Q))){
                throw ValueError("vapor quality is not in (0,1)");
            }
            else{
                CoolPropDbl TL = _HUGE, TV = _HUGE;
                if (is_mixture){
                    std::vector<std::pair<std::size_t, std::size_t> > intersect = PhaseEnvelopeRoutines::find_intersections(phase_envelope, iP, _p);
                    if (intersect.empty()){ throw ValueError(format("p [%g Pa] is not within phase envelope", _p)); }
                    iV = intersect[0].first; iL = intersect[1].first;
                }
                else{
                    bool it_is_inside = pure_saturation.is_inside(iP, _p, iQ, _Q, iL, iV, TL, TV);
                    if (!it_is_inside){
                        throw ValueError("Not possible to determine whether pressure is inside or not");
                    }
                }
                _T = _Q*TV + (1-_Q)*TL;
                cached_saturation_iL = iL; cached_saturation_iV = iV; _phase = iphase_twophase;
            }
            break;
        }
        case QT_INPUTS:{
			std::size_t iL = 0, iV = 0;
			_Q = val1; _T = val2;
            
            using_single_phase_table = false;
            if(!is_in_closed_range(0.0, 1.0, static_cast<double>(_Q))){
                throw ValueError("vapor quality is not in (0,1)");
            }
            else{
                CoolPropDbl pL, pV;
                if (is_mixture){
                    std::vector<std::pair<std::size_t,std::size_t> > intersect = PhaseEnvelopeRoutines::find_intersections(phase_envelope, iT, _T);
                    if (intersect.empty()){ throw ValueError(format("T [%g K] is not within phase envelope", _T)); }
                    iV = intersect[0].first; iL = intersect[1].first;
                    pL = PhaseEnvelopeRoutines::evaluate(phase_envelope, iP, iT, _T, iL);
                    pV = PhaseEnvelopeRoutines::evaluate(phase_envelope, iP, iT, _T, iV);
                    _p = _Q*pV + (1-_Q)*pL;
                }
                else{
                    pure_saturation.is_inside(iT, _T, iQ, _Q, iL, iV, pL, pV);
                }
                _p = _Q*pV + (1-_Q)*pL;
                cached_saturation_iL = iL; cached_saturation_iV = iV; _phase = iphase_twophase;
            }
			break;
		}
		default:
			throw ValueError("Sorry, but this set of inputs is not supported for Bicubic backend");
	}
}
void CoolProp::BicubicBackend::build_coeffs(SinglePhaseGriddedTableData &table, std::vector<std::vector<CellCoeffs> > &coeffs)
{
    if (!coeffs.empty()){ return; }
	const bool debug = get_debug_level() > 5 || false;
    const int param_count = 6;
    parameters param_list[param_count] = {iDmolar, iT, iSmolar, iHmolar, iP, iUmolar};
    std::vector<std::vector<double> > *f = NULL, *fx = NULL, *fy = NULL, *fxy = NULL;
    
	clock_t t1 = clock();

    // Resize the coefficient structures
    coeffs.resize(table.Nx - 1, std::vector<CellCoeffs>(table.Ny - 1));

    int valid_cell_count = 0;
    for (std::size_t k = 0; k < param_count; ++k){
        parameters param = param_list[k];
		if (param == table.xkey || param == table.ykey){continue;} // Skip tables that match either of the input variables
		
		switch(param){
            case iT:
                f = &(table.T); fx = &(table.dTdx); fy = &(table.dTdy); fxy = &(table.d2Tdxdy);
                break;
			case iP:
                f = &(table.p); fx = &(table.dpdx); fy = &(table.dpdy); fxy = &(table.d2pdxdy);
                break;
            case iDmolar:
                f = &(table.rhomolar); fx = &(table.drhomolardx); fy = &(table.drhomolardy); fxy = &(table.d2rhomolardxdy);
                break;
			case iSmolar:
                f = &(table.smolar); fx = &(table.dsmolardx); fy = &(table.dsmolardy); fxy = &(table.d2smolardxdy);
                break;
			case iHmolar:
                f = &(table.hmolar); fx = &(table.dhmolardx); fy = &(table.dhmolardy); fxy = &(table.d2hmolardxdy);
                break;
			case iUmolar:
				f = &(table.umolar); fx = &(table.dumolardx); fy = &(table.dumolardy); fxy = &(table.d2umolardxdy);
                break;
            default:
                throw ValueError("Invalid variable type to build_coeffs");
		}
        for (std::size_t i = 0; i < table.Nx-1; ++i) // -1 since we have one fewer cells than nodes
        {
            for (std::size_t j = 0; j < table.Ny-1; ++j) // -1 since we have one fewer cells than nodes
            {               
                if (ValidNumber((*f)[i][j]) && ValidNumber((*f)[i+1][j]) && ValidNumber((*f)[i][j+1]) && ValidNumber((*f)[i+1][j+1])){
                    
                    // This will hold the scaled f values for the cell
                    Eigen::Matrix<double, 16, 1> F;
                    // The output values (do not require scaling
                    F(0) = (*f)[i][j]; F(1) = (*f)[i+1][j]; F(2) = (*f)[i][j+1]; F(3) = (*f)[i+1][j+1]; 
                    // Scaling parameter
                    // d(f)/dxhat = df/dx * dx/dxhat, where xhat = (x-x_i)/(x_{i+1}-x_i)
                    coeffs[i][j].dx_dxhat = table.xvec[i+1]-table.xvec[i];
                    double dx_dxhat = coeffs[i][j].dx_dxhat;
                    F(4) = (*fx)[i][j]*dx_dxhat; F(5) = (*fx)[i+1][j]*dx_dxhat; 
                    F(6) = (*fx)[i][j+1]*dx_dxhat; F(7) = (*fx)[i+1][j+1]*dx_dxhat; 
                    // Scaling parameter
                    // d(f)/dyhat = df/dy * dy/dyhat, where yhat = (y-y_j)/(y_{j+1}-y_j)
                    coeffs[i][j].dy_dyhat = table.yvec[j+1]-table.yvec[j];
                    double dy_dyhat = coeffs[i][j].dy_dyhat;
                    F(8) = (*fy)[i][j]*dy_dyhat; F(9) = (*fy)[i+1][j]*dy_dyhat; 
                    F(10) = (*fy)[i][j+1]*dy_dyhat; F(11) = (*fy)[i+1][j+1]*dy_dyhat; 
                    // Cross derivatives are doubly scaled following the examples above
                    F(12) = (*fxy)[i][j]*dy_dyhat*dx_dxhat; F(13) = (*fxy)[i+1][j]*dy_dyhat*dx_dxhat; 
                    F(14) = (*fxy)[i][j+1]*dy_dyhat*dx_dxhat; F(15) = (*fxy)[i+1][j+1]*dy_dyhat*dx_dxhat; 
					// Calculate the alpha coefficients
					Eigen::MatrixXd alpha = Ainv.transpose()*F; // 16x1; Watch out for the transpose!
					std::vector<double> valpha = eigen_to_vec1D(alpha);
                    coeffs[i][j].set(param, valpha);
                    coeffs[i][j].set_valid();
					valid_cell_count++;
                }
                else{
                    coeffs[i][j].set_invalid();
                }
            }
        }
        double elapsed = (clock() - t1)/((double)CLOCKS_PER_SEC);
        if (debug){
            std::cout << format("Calculated bicubic coefficients for %d good cells in %g sec.\n", valid_cell_count, elapsed);
        }
        std::size_t remap_count = 0;
        // Now find invalid cells and give them pointers to a neighboring cell that works
        for (std::size_t i = 0; i < table.Nx-1; ++i) // -1 since we have one fewer cells than nodes
        {
            for (std::size_t j = 0; j < table.Ny-1; ++j) // -1 since we have one fewer cells than nodes
            {
                // Not a valid cell
                if (!coeffs[i][j].valid()){
                    // Offsets that we are going to try in order (left, right, top, bottom, diagonals)
                    int xoffsets[] = {-1,1,0,0,-1,1,1,-1};
                    int yoffsets[] = {0,0,1,-1,-1,-1,1,1};
                    // Length of offset
                    std::size_t N = sizeof(xoffsets)/sizeof(xoffsets[0]);
                    for (std::size_t k = 0; k < N; ++k){
                        std::size_t iplus = i + xoffsets[k];
                        std::size_t jplus = j + yoffsets[k];
                        if (0 < iplus && iplus < table.Nx-1 && 0 < jplus && jplus < table.Ny-1 && coeffs[iplus][jplus].valid()){
                            coeffs[i][j].set_alternate(iplus, jplus);
                            remap_count++;
                            if (debug){std::cout << format("Mapping %d,%d to %d,%d\n",i,j,iplus,jplus);}
                            break;
                        }
                    }
                }
            }
        }
        if (debug){
            std::cout << format("Remapped %d cells\n", remap_count);
        }
    }
}