Пример #1
0
EXPORT CLASS *init(CALLBACKS *fntable, MODULE *module, int argc, char *argv[])
{
	PROPERTYTYPE p;

	if(sizeof(void *) == sizeof(int32))
		p = PT_int32;
	if(sizeof(void *) == sizeof(int64))
		p = PT_int64;

	// set the GridLAB core API callback table
	callback = fntable;


	gl_global_create("glmjava::classpath",PT_char256,get_classpath(),NULL);
	gl_global_create("glmjava::libpath",PT_char256,get_libpath(),NULL);
	gl_global_create("glmjava::jcallback",p,get_jcb(),PT_ACCESS,PA_REFERENCE,NULL);
	//	default values
	strcpy(get_classpath(), "Win32/Debug/");
	strcpy(get_libpath(), "Win32/Debug/");


//	if(get_jvm() == NULL){
//		gl_error("Unable to initialize JVM in java->init()");
//		return NULL;
//	}

	// very nonstandard.
	return new_holder(module);
}
Пример #2
0
EXPORT CLASS *init(CALLBACKS *fntable, MODULE *module, int argc, char *argv[])
{
	if (set_callback(fntable)==NULL)
	{
		errno = EINVAL;
		return NULL;
	}
	pGlobalClock = fntable->global_clock;
	gl_global_getvar("execdir",libpath,sizeof(libpath));
	strcat(libpath,"/plc/lib");
	gl_global_create("plc::libpath",PT_char1024,libpath,NULL);

	gl_global_getvar("execdir",incpath,sizeof(incpath));
	strcat(incpath,"/plc/include");
	gl_global_create("plc::incpath",PT_char1024,incpath,NULL);

	new plc(module);
	new comm(module);

	/* always return the first class registered */
	return plc::oclass;
}
Пример #3
0
EXPORT CLASS *init(CALLBACKS *fntable, MODULE *module, int argc, char *argv[])
{
	if (set_callback(fntable)==NULL)
	{
		errno = EINVAL;
		return NULL;
	}

	Socket::init();

	gl_global_create("connection::security",PT_enumeration,&connection_security,
		PT_DESCRIPTION, "default connection security level",
		PT_KEYWORD, "NONE", (enumeration)CS_NONE,
		PT_KEYWORD, "LOW", (enumeration)CS_LOW,
		PT_KEYWORD, "STANDARD", (enumeration)CS_STANDARD,
		PT_KEYWORD, "HIGH", (enumeration)CS_HIGH,
		PT_KEYWORD, "EXTREME", (enumeration)CS_EXTREME,
		PT_KEYWORD, "PARANOID", (enumeration)CS_PARANOID,
		NULL);
	gl_global_create("connection::lockout",PT_double,&connection_lockout,
		PT_UNITS, "s",
		PT_DESCRIPTION, "default connection security lockout time",
		NULL);
	gl_global_create("connection::enable_subsecond_models", PT_bool, &enable_subsecond_models,PT_DESCRIPTION,"Enable deltamode capabilities within the connection module",NULL);

	new native(module);
//	new xml(module); // TODO finish XML implementation
	new json(module);
#if HAVE_FNCS
	new fncs_msg(module);
#endif
	// TODO add new classes before this line

	/* always return the first class registered */
	return native::oclass;
}
Пример #4
0
EXPORT CLASS *init(CALLBACKS *fntable, MODULE *module, int argc, char *argv[])
{
	if (set_callback(fntable)==NULL)
	{
		errno = EINVAL;
		return NULL;
	}

	gl_global_create("residential::default_line_voltage",PT_complex,&default_line_voltage,PT_SIZE,3,PT_UNITS,"V",PT_DESCRIPTION,"line voltage to use when no circuit is attached",NULL);
	gl_global_create("residential::default_line_current",PT_complex,&default_line_current,PT_SIZE,3,PT_UNITS,"A",PT_DESCRIPTION,"line current calculated when no circuit is attached",NULL);
	gl_global_create("residential::default_outdoor_temperature",PT_double,&default_outdoor_temperature,PT_UNITS,"degF",PT_DESCRIPTION,"outdoor air temperature when no climate data is found",NULL);
	gl_global_create("residential::default_humidity",PT_double,&default_humidity,PT_UNITS,"%",PT_DESCRIPTION,"humidity when no climate data is found",NULL);
	gl_global_create("residential::default_solar",PT_double,&default_solar,PT_SIZE,9,PT_UNITS,"Btu/sf",PT_DESCRIPTION,"solar gains when no climate data is found",NULL);
	gl_global_create("residential::default_etp_iterations",PT_int64,&default_etp_iterations,PT_DESCRIPTION,"number of iterations ETP solver will run",NULL);
	gl_global_create("residential::ANSI_voltage_check",PT_bool,&ANSI_voltage_check,PT_DESCRIPTION,"enable or disable messages about ANSI voltage limit violations in the house",NULL);

	new residential_enduse(module);
	new appliance(module);
	// obsolete as of 3.0: new house(module);
	new house_e(module);
	new waterheater(module);
	new lights(module);
	new refrigerator(module);
	new clotheswasher(module);
	new dishwasher(module);
	new occupantload(module);
	new plugload(module);
	new microwave(module);
	new range(module);
	new freezer(module);
	new dryer(module);
	new evcharger(module);
	new ZIPload(module);
	new thermal_storage(module);
	new evcharger_det(module);
	new soil_sensor(module);


	/* always return the first class registered */
	return residential_enduse::oclass;
}
Пример #5
0
EXPORT CLASS *init(CALLBACKS *fntable, MODULE *module, int argc, char *argv[])
{
	if (!set_callback(fntable)) {
		errno = EINVAL;
		return NULL;
	}

	/* exported globals */
	gl_global_create("powerflow::show_matrix_values",PT_bool,&show_matrix_values,NULL);
	gl_global_create("powerflow::primary_voltage_ratio",PT_double,&primary_voltage_ratio,NULL);
	gl_global_create("powerflow::nominal_frequency",PT_double,&nominal_frequency,NULL);
	gl_global_create("powerflow::require_voltage_control", PT_bool,&require_voltage_control,NULL);
	gl_global_create("powerflow::geographic_degree",PT_double,&geographic_degree,NULL);
	gl_global_create("powerflow::fault_impedance",PT_complex,&fault_Z,NULL);
	gl_global_create("powerflow::warning_underfrequency",PT_double,&warning_underfrequency,NULL);
	gl_global_create("powerflow::warning_overfrequency",PT_double,&warning_overfrequency,NULL);
	gl_global_create("powerflow::warning_undervoltage",PT_double,&warning_undervoltage,NULL);
	gl_global_create("powerflow::warning_overvoltage",PT_double,&warning_overvoltage,NULL);
	gl_global_create("powerflow::warning_voltageangle",PT_double,&warning_voltageangle,NULL);
	gl_global_create("powerflow::maximum_voltage_error",PT_double,&default_maximum_voltage_error,NULL);
	gl_global_create("powerflow::solver_method",PT_enumeration,&solver_method,
		PT_KEYWORD,"FBS",SM_FBS,
		PT_KEYWORD,"GS",SM_GS,
		PT_KEYWORD,"NR",SM_NR,
		NULL);
	gl_global_create("powerflow::lu_solver",PT_char256,&LUSolverName,NULL);
	gl_global_create("powerflow::acceleration_factor",PT_double,&acceleration_factor,NULL);
	gl_global_create("powerflow::NR_iteration_limit",PT_int64,&NR_iteration_limit,NULL);
	gl_global_create("powerflow::NR_superLU_procs",PT_int32,&NR_superLU_procs,NULL);
	gl_global_create("powerflow::default_maximum_voltage_error",PT_double,&default_maximum_voltage_error,NULL);

	// register each object class by creating the default instance
	new powerflow_object(module);
	new powerflow_library(module);
	new node(module);
	new link(module);
	new capacitor(module);
	new fuse(module);
	new meter(module);
	new line(module);
	new line_spacing(module);
    new overhead_line(module);
    new underground_line(module);
    new overhead_line_conductor(module);
    new underground_line_conductor(module);
    new line_configuration(module);
	new relay(module);
	new transformer_configuration(module);
	new transformer(module);
	new load(module);
	new regulator_configuration(module);
	new regulator(module);
	new triplex_node(module);
	new triplex_meter(module);
	new triplex_line(module);
	new triplex_line_configuration(module);
	new triplex_line_conductor(module);
	new switch_object(module);
	new substation(module);
	new pqload(module);
	new voltdump(module);
	new series_reactor(module);
	new restoration(module);
	new frequency_gen(module);
	new volt_var_control(module);
	new fault_check(module);
	new motor(module);
	new billdump(module);
	new power_metrics(module);
	new currdump(module);
	new recloser(module);
	new sectionalizer(module);
	new emissions(module);

	/* always return the first class registered */
	return node::oclass;
}
Пример #6
0
EXPORT CLASS *init(CALLBACKS *fntable, MODULE *module, int argc, char *argv[])
{
	if (!set_callback(fntable)) {
		errno = EINVAL;
		return NULL;
	}

	/* exported globals */
	gl_global_create("powerflow::show_matrix_values",PT_bool,&show_matrix_values,NULL);
	gl_global_create("powerflow::primary_voltage_ratio",PT_double,&primary_voltage_ratio,NULL);
	gl_global_create("powerflow::nominal_frequency",PT_double,&nominal_frequency,NULL);
	gl_global_create("powerflow::require_voltage_control", PT_bool,&require_voltage_control,NULL);
	gl_global_create("powerflow::geographic_degree",PT_double,&geographic_degree,NULL);
	gl_global_create("powerflow::fault_impedance",PT_complex,&fault_Z,NULL);
	gl_global_create("powerflow::warning_underfrequency",PT_double,&warning_underfrequency,NULL);
	gl_global_create("powerflow::warning_overfrequency",PT_double,&warning_overfrequency,NULL);
	gl_global_create("powerflow::warning_undervoltage",PT_double,&warning_undervoltage,NULL);
	gl_global_create("powerflow::warning_overvoltage",PT_double,&warning_overvoltage,NULL);
	gl_global_create("powerflow::warning_voltageangle",PT_double,&warning_voltageangle,NULL);
	gl_global_create("powerflow::maximum_voltage_error",PT_double,&default_maximum_voltage_error,NULL);
	gl_global_create("powerflow::solver_method",PT_enumeration,&solver_method,
		PT_KEYWORD,"FBS",SM_FBS,
		PT_KEYWORD,"GS",SM_GS,
		PT_KEYWORD,"NR",SM_NR,
		NULL);
	gl_global_create("powerflow::line_capacitance",PT_bool,&use_line_cap,NULL);
	gl_global_create("powerflow::line_limits",PT_bool,&use_link_limits,NULL);
	gl_global_create("powerflow::lu_solver",PT_char256,&LUSolverName,NULL);
	gl_global_create("powerflow::NR_iteration_limit",PT_int64,&NR_iteration_limit,NULL);
	gl_global_create("powerflow::NR_superLU_procs",PT_int32,&NR_superLU_procs,NULL);
	gl_global_create("powerflow::default_maximum_voltage_error",PT_double,&default_maximum_voltage_error,NULL);
	gl_global_create("powerflow::default_maximum_power_error",PT_double,&default_maximum_power_error,NULL);
	gl_global_create("powerflow::NR_admit_change",PT_bool,&NR_admit_change,NULL);
	gl_global_create("powerflow::enable_subsecond_models", PT_bool, &enable_subsecond_models,PT_DESCRIPTION,"Enable deltamode capabilities within the powerflow module",NULL);
	gl_global_create("powerflow::all_powerflow_delta", PT_bool, &all_powerflow_delta,PT_DESCRIPTION,"Forces all powerflow objects that are capable to participate in deltamode",NULL);
	gl_global_create("powerflow::deltamode_timestep", PT_double, &deltamode_timestep_publish,PT_UNITS,"ns",PT_DESCRIPTION,"Desired minimum timestep for deltamode-related simulations",NULL);
	gl_global_create("powerflow::deltamode_extra_function", PT_int64, &deltamode_extra_function,NULL);
	gl_global_create("powerflow::current_frequency",PT_double,&current_frequency,PT_UNITS,"Hz",PT_DESCRIPTION,"Current system-level frequency of the powerflow system",NULL);
	gl_global_create("powerflow::master_frequency_update",PT_bool,&master_frequency_update,PT_DESCRIPTION,"Tracking variable to see if an object has become the system frequency updater",NULL);
	gl_global_create("powerflow::enable_frequency_dependence",PT_bool,&enable_frequency_dependence,PT_DESCRIPTION,"Flag to enable frequency-based variations in impedance values of lines and loads",NULL);
	gl_global_create("powerflow::default_resistance",PT_double,&default_resistance,NULL);

	// register each object class by creating the default instance
	new powerflow_object(module);
	new powerflow_library(module);
	new node(module);
	new link_object(module);
	new capacitor(module);
	new fuse(module);
	new meter(module);
	new line(module);
	new line_spacing(module);
    new overhead_line(module);
    new underground_line(module);
    new overhead_line_conductor(module);
    new underground_line_conductor(module);
    new line_configuration(module);
	new transformer_configuration(module);
	new transformer(module);
	new load(module);
	new regulator_configuration(module);
	new regulator(module);
	new triplex_node(module);
	new triplex_meter(module);
	new triplex_line(module);
	new triplex_line_configuration(module);
	new triplex_line_conductor(module);
	new switch_object(module);
	new substation(module);
	new pqload(module);
	new voltdump(module);
	new series_reactor(module);
	new restoration(module);
	new frequency_gen(module);
	new volt_var_control(module);
	new fault_check(module);
	new motor(module);
	new billdump(module);
	new power_metrics(module);
	new currdump(module);
	new recloser(module);
	new sectionalizer(module);
	new emissions(module);
	new load_tracker(module);
	new triplex_load(module);

	/* always return the first class registered */
	return node::oclass;
}
Пример #7
0
// the constructor registers the class and properties and sets the defaults
triplex_meter::triplex_meter(MODULE *mod) : triplex_node(mod)
{
	// first time init
	if (oclass==NULL)
	{
		// link to parent class (used by isa)
		pclass = triplex_node::oclass;

		// register the class definition
		oclass = gl_register_class(mod,"triplex_meter",sizeof(triplex_meter),PC_PRETOPDOWN|PC_BOTTOMUP|PC_POSTTOPDOWN|PC_UNSAFE_OVERRIDE_OMIT|PC_AUTOLOCK);
		if (oclass==NULL)
			throw "unable to register class triplex_meter";
		else
			oclass->trl = TRL_PROVEN;

		// publish the class properties
		if (gl_publish_variable(oclass,
			PT_INHERIT, "triplex_node",
			PT_double, "measured_real_energy[Wh]", PADDR(measured_real_energy),PT_DESCRIPTION,"metered real energy consumption",
			PT_double, "measured_reactive_energy[VAh]",PADDR(measured_reactive_energy),PT_DESCRIPTION,"metered reactive energy consumption",
			PT_complex, "measured_power[VA]", PADDR(measured_power),PT_DESCRIPTION,"metered power",
			PT_complex, "indiv_measured_power_1[VA]", PADDR(indiv_measured_power[0]),PT_DESCRIPTION,"metered power, phase 1",
			PT_complex, "indiv_measured_power_2[VA]", PADDR(indiv_measured_power[1]),PT_DESCRIPTION,"metered power, phase 2",
			PT_complex, "indiv_measured_power_N[VA]", PADDR(indiv_measured_power[2]),PT_DESCRIPTION,"metered power, phase N",
			PT_double, "measured_demand[W]", PADDR(measured_demand),PT_DESCRIPTION,"metered demand (peak of power)",
			PT_double, "measured_real_power[W]", PADDR(measured_real_power),PT_DESCRIPTION,"metered real power",
			PT_double, "measured_reactive_power[VAr]", PADDR(measured_reactive_power),PT_DESCRIPTION,"metered reactive power",
			PT_complex, "meter_power_consumption[VA]", PADDR(tpmeter_power_consumption),PT_DESCRIPTION,"power consumed by meter operation",

			// added to record last voltage/current
			PT_complex, "measured_voltage_1[V]", PADDR(measured_voltage[0]),PT_DESCRIPTION,"measured voltage, phase 1 to ground",
			PT_complex, "measured_voltage_2[V]", PADDR(measured_voltage[1]),PT_DESCRIPTION,"measured voltage, phase 2 to ground",
			PT_complex, "measured_voltage_N[V]", PADDR(measured_voltage[2]),PT_DESCRIPTION,"measured voltage, phase N to ground",
			PT_complex, "measured_current_1[A]", PADDR(measured_current[0]),PT_DESCRIPTION,"measured current, phase 1",
			PT_complex, "measured_current_2[A]", PADDR(measured_current[1]),PT_DESCRIPTION,"measured current, phase 2",
			PT_complex, "measured_current_N[A]", PADDR(measured_current[2]),PT_DESCRIPTION,"measured current, phase N",
			PT_bool, "customer_interrupted", PADDR(tpmeter_interrupted),PT_DESCRIPTION,"Reliability flag - goes active if the customer is in an interrupted state",
			PT_bool, "customer_interrupted_secondary", PADDR(tpmeter_interrupted_secondary),PT_DESCRIPTION,"Reliability flag - goes active if the customer is in a secondary interrupted state - i.e., momentary",
#ifdef SUPPORT_OUTAGES
			PT_int16, "sustained_count", PADDR(sustained_count),PT_DESCRIPTION,"reliability sustained event counter",
			PT_int16, "momentary_count", PADDR(momentary_count),PT_DESCRIPTION,"reliability momentary event counter",
			PT_int16, "total_count", PADDR(total_count),PT_DESCRIPTION,"reliability total event counter",
			PT_int16, "s_flag", PADDR(s_flag),PT_DESCRIPTION,"reliability flag that gets set if the meter experienced more than n sustained interruptions",
			PT_int16, "t_flag", PADDR(t_flag),PT_DESCRIPTION,"reliability flage that gets set if the meter experienced more than n events total",
			PT_complex, "pre_load", PADDR(pre_load),PT_DESCRIPTION,"the load prior to being interrupted",
#endif

			PT_double, "monthly_bill[$]", PADDR(monthly_bill),PT_DESCRIPTION,"Accumulator for the current month's bill",
			PT_double, "previous_monthly_bill[$]", PADDR(previous_monthly_bill),PT_DESCRIPTION,"Total monthly bill for the previous month",
			PT_double, "previous_monthly_energy[kWh]", PADDR(previous_monthly_energy),PT_DESCRIPTION,"",
			PT_double, "monthly_fee[$]", PADDR(monthly_fee),PT_DESCRIPTION,"Total monthly energy for the previous month",
			PT_double, "monthly_energy[kWh]", PADDR(monthly_energy),PT_DESCRIPTION,"Accumulator for the current month's energy",
			PT_enumeration, "bill_mode", PADDR(bill_mode),PT_DESCRIPTION,"Designates the bill mode to be used",
				PT_KEYWORD,"NONE",(enumeration)BM_NONE,
				PT_KEYWORD,"UNIFORM",(enumeration)BM_UNIFORM,
				PT_KEYWORD,"TIERED",(enumeration)BM_TIERED,
				PT_KEYWORD,"HOURLY",(enumeration)BM_HOURLY,
				PT_KEYWORD,"TIERED_RTP",(enumeration)BM_TIERED_RTP,
			PT_object, "power_market", PADDR(power_market),PT_DESCRIPTION,"Designates the auction object where prices are read from for bill mode",
			PT_int32, "bill_day", PADDR(bill_day),PT_DESCRIPTION,"Day bill is to be processed (assumed to occur at midnight of that day)",
			PT_double, "price[$/kWh]", PADDR(price),PT_DESCRIPTION,"Standard uniform pricing",
			PT_double, "price_base[$/kWh]", PADDR(price_base), PT_DESCRIPTION, "Used only in TIERED_RTP mode to describe the price before the first tier",
			PT_double, "first_tier_price[$/kWh]", PADDR(tier_price[0]),PT_DESCRIPTION,"first tier price of energy between first and second tier energy",
			PT_double, "first_tier_energy[kWh]", PADDR(tier_energy[0]),PT_DESCRIPTION,"price of energy on tier above price or price base",
			PT_double, "second_tier_price[$/kWh]", PADDR(tier_price[1]),PT_DESCRIPTION,"first tier price of energy between second and third tier energy",
			PT_double, "second_tier_energy[kWh]", PADDR(tier_energy[1]),PT_DESCRIPTION,"price of energy on tier above first tier",
			PT_double, "third_tier_price[$/kWh]", PADDR(tier_price[2]),PT_DESCRIPTION,"first tier price of energy greater than third tier energy",
			PT_double, "third_tier_energy[kWh]", PADDR(tier_energy[2]),PT_DESCRIPTION,"price of energy on tier above second tier",

			NULL)<1) GL_THROW("unable to publish properties in %s",__FILE__);

			//Deltamode functions
			if (gl_publish_function(oclass,	"delta_linkage_node", (FUNCTIONADDR)delta_linkage)==NULL)
				GL_THROW("Unable to publish triplex_meter delta_linkage function");
			if (gl_publish_function(oclass,	"interupdate_pwr_object", (FUNCTIONADDR)interupdate_triplex_meter)==NULL)
				GL_THROW("Unable to publish triplex_meter deltamode function");
			if (gl_publish_function(oclass,	"delta_freq_pwr_object", (FUNCTIONADDR)delta_frequency_node)==NULL)
				GL_THROW("Unable to publish triplex_meter deltamode function");

                        // market price name
                        gl_global_create("powerflow::market_price_name",PT_char1024,&market_price_name,NULL);
		}
}
Пример #8
0
EXPORT bool glx_init(glxlink *mod)
{
	gl_verbose("initializing matlab link");
	gl_verbose("PATH=%s", getenv("PATH"));

	// initialize matlab engine
	MATLABLINK *matlab = (MATLABLINK*)mod->get_data();
	matlab->status = 0;
#ifdef WIN32
	if ( matlab->command )
		matlab->engine = engOpen(matlab->command);
	else
		matlab->engine = engOpenSingleUse(NULL,NULL,&matlab->status);
	if ( matlab->engine==NULL )
	{
		gl_error("matlab engine start failed, status code is '%d'", matlab->status);
		return false;
	}
#else
	matlab->engine = engOpen(matlab->command);
	if ( matlab->engine==NULL )
	{
		gl_error("matlab engine start failed");
		return false;
	}
#endif

	// set the output buffer
	if ( matlab->output_buffer!=NULL )
		engOutputBuffer(matlab->engine,matlab->output_buffer,(int)matlab->output_size);

	// setup matlab engine
	engSetVisible(matlab->engine,window_show(matlab));

	gl_debug("matlab link is open");

	// special values needed by matlab
	mxArray *ts_never = mxCreateDoubleScalar((double)(TIMESTAMP)TS_NEVER);
	engPutVariable(matlab->engine,"TS_NEVER",ts_never);
	mxArray *ts_error = mxCreateDoubleScalar((double)(TIMESTAMP)TS_INVALID);
	engPutVariable(matlab->engine,"TS_ERROR",ts_error);
	mxArray *gld_ok = mxCreateDoubleScalar((double)(bool)true);
	engPutVariable(matlab->engine,"GLD_OK",gld_ok);
	mxArray *gld_err = mxCreateDoubleScalar((double)(bool)false);
	engPutVariable(matlab->engine,"GLD_ERROR",gld_err);

	// set the workdir
	if ( strcmp(matlab->workdir,"")!=0 )
	{
#ifdef WIN32
		_mkdir(matlab->workdir);
#else
		mkdir(matlab->workdir,0750);
#endif
		if ( matlab->workdir[0]=='/' )
			matlab_exec(matlab,"cd '%s'", matlab->workdir);
		else
			matlab_exec(matlab,"cd '%s/%s'", getcwd(NULL,0),matlab->workdir);
	}

	// run the initialization command(s)
	if ( matlab->init )
	{
		mxArray *ans = matlab_exec(matlab,"%s",matlab->init);
		if ( ans && mxIsDouble(ans) && (bool)*mxGetPr(ans)==false )
		{
			gl_error("matlab init failed");
			return false;
		}
		else if ( ans && mxIsChar(ans) )
		{
			int buflen = (mxGetM(ans) * mxGetN(ans)) + 1;
			char *string =(char*)malloc(buflen);
			int status_error = mxGetString(ans, string, buflen);
			if (status_error == 0)
			{
				gl_error("'%s'",string);
				return false;
			}
			else
			{			
				gl_error("Did not catch Matlab error");
				return false;
			}
		}
	}

	if ( matlab->rootname!=NULL )
	{
		// build gridlabd data
		mwSize dims[] = {1,1};
		mxArray *gridlabd_struct = mxCreateStructArray(2,dims,0,NULL);

		///////////////////////////////////////////////////////////////////////////
		// build global data
		LINKLIST *item;
		mxArray *global_struct = mxCreateStructArray(2,dims,0,NULL);
		for ( item=mod->get_globals() ; item!=NULL ; item=mod->get_next(item) )
		{
			char *name = mod->get_name(item);
			GLOBALVAR *var = mod->get_globalvar(item);
			mxArray *var_struct = NULL;
			mwIndex var_index;
			if ( var==NULL ) continue;

			// do not map module or structured globals
			if ( strchr(var->prop->name,':')!=NULL )
			{
				// ignore module globals here
			}
			else if ( strchr(var->prop->name,'.')!=NULL )
			{
				char struct_name[256];
				if ( sscanf(var->prop->name,"%[^.]",struct_name)==0 )
				{
					gld_property prop(var);
					var_index = mxAddField(global_struct,prop.get_name());
					var_struct = matlab_create_value(&prop);
					if ( var_struct!=NULL )
					{
						//mod->add_copyto(var->prop->addr,mxGetData(var_struct));
						mxSetFieldByNumber(global_struct,0,var_index,var_struct);
					}
				}
			}
			else // simple data
			{
				gld_property prop(var);
				var_index = mxAddField(global_struct,prop.get_name());
				var_struct = matlab_create_value(&prop);
				if ( var_struct!=NULL )
				{
					//mod->add_copyto(var->prop->addr,mxGetData(var_struct));
					mxSetFieldByNumber(global_struct,0,var_index,var_struct);
				}
			}

			// update export list
			if ( var_struct!=NULL )
			{
				mod->set_addr(item,(void*)var_struct);
				mod->set_index(item,(size_t)var_index);
			}
		}

		// add globals structure to gridlabd structure
		mwIndex gridlabd_index = mxAddField(gridlabd_struct,"global");
		mxSetFieldByNumber(gridlabd_struct,0,gridlabd_index,global_struct);

		///////////////////////////////////////////////////////////////////////////
		// build module data
		dims[0] = dims[1] = 1;
		mxArray *module_struct = mxCreateStructArray(2,dims,0,NULL);

		// add modules
		for ( MODULE *module = callback->module.getfirst() ; module!=NULL ; module=module->next )
		{
			// create module info struct
			mwIndex dims[] = {1,1};
			mxArray *module_data = mxCreateStructArray(2,dims,0,NULL);
			mwIndex module_index = mxAddField(module_struct,module->name);
			mxSetFieldByNumber(module_struct,0,module_index,module_data);
			
			// create version info struct
			const char *version_fields[] = {"major","minor"};
			mxArray *version_data = mxCreateStructArray(2,dims,sizeof(version_fields)/sizeof(version_fields[0]),version_fields);
			mxArray *major_data = mxCreateDoubleScalar((double)module->major);
			mxArray *minor_data = mxCreateDoubleScalar((double)module->minor);
			mxSetFieldByNumber(version_data,0,0,major_data);
			mxSetFieldByNumber(version_data,0,1,minor_data);

			// attach version info to module info
			mwIndex version_index = mxAddField(module_data,"version");
			mxSetFieldByNumber(module_data,0,version_index,version_data);

		}
		gridlabd_index = mxAddField(gridlabd_struct,"module");
		mxSetFieldByNumber(gridlabd_struct,0,gridlabd_index,module_struct);

		///////////////////////////////////////////////////////////////////////////
		// build class data
		dims[0] = dims[1] = 1;
		mxArray *class_struct = mxCreateStructArray(2,dims,0,NULL);
		gridlabd_index = mxAddField(gridlabd_struct,"class");
		mxSetFieldByNumber(gridlabd_struct,0,gridlabd_index,class_struct);
		mwIndex class_id[1024]; // index into class struct
		memset(class_id,0,sizeof(class_id));

		// add classes
		for ( CLASS *oclass = callback->class_getfirst() ; oclass!=NULL ; oclass=oclass->next )
		{
			// count objects in this class
			mwIndex dims[] = {0,1};
			for ( item=mod->get_objects() ; item!=NULL ; item=mod->get_next(item) )
			{
				OBJECT *obj = mod->get_object(item);
				if ( obj==NULL || obj->oclass!=oclass ) continue;
				dims[0]++;
			}
			if ( dims[0]==0 ) continue;
			mxArray *runtime_struct = mxCreateStructArray(2,dims,0,NULL);

			// add class 
			mwIndex class_index = mxAddField(class_struct,oclass->name);
			mxSetFieldByNumber(class_struct,0,class_index,runtime_struct);

			// add properties to class
			for ( PROPERTY *prop=oclass->pmap ; prop!=NULL && prop->oclass==oclass ; prop=prop->next )
			{
				mwIndex dims[] = {1,1};
				mxArray *property_struct = mxCreateStructArray(2,dims,0,NULL);
				mwIndex runtime_index = mxAddField(runtime_struct,prop->name);
				mxSetFieldByNumber(runtime_struct,0,runtime_index,property_struct);
			}

			// add objects to class
			for ( item=mod->get_objects() ; item!=NULL ; item=mod->get_next(item) )
			{
				OBJECT *obj = mod->get_object(item);
				if ( obj==NULL || obj->oclass!=oclass ) continue;
				mwIndex index = class_id[obj->oclass->id]++;
				
				// add properties to class
				for ( PROPERTY *prop=oclass->pmap ; prop!=NULL && prop->oclass==oclass ; prop=prop->next )
				{
					gld_property p(obj,prop);
					mxArray *data = matlab_create_value(&p);
					mxSetField(runtime_struct,index,prop->name,data);
				}

				// update export list
				mod->set_addr(item,(void*)runtime_struct);
				mod->set_index(item,(size_t)index);
			}
		}

		///////////////////////////////////////////////////////////////////////////
		// build the object data
		dims[0] = 0;
		for ( item=mod->get_objects() ; item!=NULL ; item=mod->get_next(item) )
		{
			if ( mod->get_object(item)!=NULL ) dims[0]++;
		}
		dims[1] = 1;
		memset(class_id,0,sizeof(class_id));
		const char *objfields[] = {"name","class","id","parent","rank","clock","valid_to","schedule_skew",
			"latitude","longitude","in","out","rng_state","heartbeat","lock","flags"};
		mxArray *object_struct = mxCreateStructArray(2,dims,sizeof(objfields)/sizeof(objfields[0]),objfields);
		mwIndex n=0;
		for ( item=mod->get_objects() ; item!=NULL ; item=mod->get_next(item) )
		{
			OBJECT *obj = mod->get_object(item);
			if ( obj==NULL ) continue;
			class_id[obj->oclass->id]++; // index into class struct

			const char *objname[] = {obj->name&&isdigit(obj->name[0])?NULL:obj->name};
			const char *oclassname[] = {obj->oclass->name};

			if (obj->name) mxSetFieldByNumber(object_struct,n,0,mxCreateCharMatrixFromStrings(mwSize(1),objname));
			mxSetFieldByNumber(object_struct,n,1,mxCreateCharMatrixFromStrings(mwSize(1),oclassname));
			mxSetFieldByNumber(object_struct,n,2,mxCreateDoubleScalar((double)class_id[obj->oclass->id]));
			if (obj->parent) mxSetFieldByNumber(object_struct,n,3,mxCreateDoubleScalar((double)obj->parent->id+1));
			mxSetFieldByNumber(object_struct,n,4,mxCreateDoubleScalar((double)obj->rank));
			mxSetFieldByNumber(object_struct,n,5,mxCreateDoubleScalar((double)obj->clock));
			mxSetFieldByNumber(object_struct,n,6,mxCreateDoubleScalar((double)obj->valid_to));
			mxSetFieldByNumber(object_struct,n,7,mxCreateDoubleScalar((double)obj->schedule_skew));
			if ( isfinite(obj->latitude) ) mxSetFieldByNumber(object_struct,n,8,mxCreateDoubleScalar((double)obj->latitude));
			if ( isfinite(obj->longitude) ) mxSetFieldByNumber(object_struct,n,9,mxCreateDoubleScalar((double)obj->longitude));
			mxSetFieldByNumber(object_struct,n,10,mxCreateDoubleScalar((double)obj->in_svc));
			mxSetFieldByNumber(object_struct,n,11,mxCreateDoubleScalar((double)obj->out_svc));
			mxSetFieldByNumber(object_struct,n,12,mxCreateDoubleScalar((double)obj->rng_state));
			mxSetFieldByNumber(object_struct,n,13,mxCreateDoubleScalar((double)obj->heartbeat));
			mxSetFieldByNumber(object_struct,n,14,mxCreateDoubleScalar((double)obj->lock));
			mxSetFieldByNumber(object_struct,n,15,mxCreateDoubleScalar((double)obj->flags));
			n++;
		}
		gridlabd_index = mxAddField(gridlabd_struct,"object");
		mxSetFieldByNumber(gridlabd_struct,0,gridlabd_index,object_struct);

		///////////////////////////////////////////////////////////////////////////
		// post the gridlabd structure
		matlab->root = gridlabd_struct;
		engPutVariable(matlab->engine,matlab->rootname,matlab->root);
	}

	///////////////////////////////////////////////////////////////////////////
	// build the import/export data
	for ( LINKLIST *item=mod->get_exports() ; item!=NULL ; item=mod->get_next(item) )
	{
		OBJECTPROPERTY *objprop = mod->get_export(item);
		if ( objprop==NULL ) continue;

		// add to published items
		gld_property prop(objprop->obj,objprop->prop);
		item->addr = (mxArray*)matlab_create_value(&prop);
		engPutVariable(matlab->engine,item->name,(mxArray*)item->addr);
	}
	for ( LINKLIST *item=mod->get_imports() ; item!=NULL ; item=mod->get_next(item) )
	{
		OBJECTPROPERTY *objprop = mod->get_import(item);
		if ( objprop==NULL ) continue;

		// check that not already in export list
		LINKLIST *export_item;
		bool found=false;
		for ( export_item=mod->get_exports() ; export_item!=NULL ; export_item=mod->get_next(export_item) )
		{
			OBJECTPROPERTY *other = mod->get_export(item);
			if ( memcmp(objprop,other,sizeof(OBJECTPROPERTY)) )
				found=true;
		}
		if ( !found )
		{
			gld_property prop(objprop->obj,objprop->prop);
			item->addr = (mxArray*)matlab_create_value(&prop);
			engPutVariable(matlab->engine,item->name,(mxArray*)item->addr);
		}
	}

	static int32 matlab_flag = 1;
	gl_global_create("MATLAB",PT_int32,&matlab_flag,PT_ACCESS,PA_REFERENCE,PT_DESCRIPTION,"indicates that MATLAB is available",NULL);
	mod->last_t = gl_globalclock;
	return true;
}